예제 #1
0
        public void Disassemble(Action <ChunkItem> callback = null)
        {
            void HandleChunk(ChunkItem chunk)
            {
                callback?.Invoke(chunk);
                Chunks.Add(chunk);
            }

            if (Metadata.Codec == CodecKind.FGDM ||
                Metadata.Codec == CodecKind.FGDC)
            {
                if (ChunkItem.Read(_input) is FileVersionChunk version &&
                    ChunkItem.Read(_input) is FileCompressionTypesChunk compressionTypes &&
                    ChunkItem.Read(_input) is AfterburnerMapChunk afterburnerMap &&
                    ChunkItem.Read(_input) is FGEIChunk fgei)
                {
                    var ilsChunk = fgei.ReadInitialLoadSegment(afterburnerMap.Entries[0]);

                    fgei.ReadChunks(afterburnerMap.Entries, HandleChunk);
                    ilsChunk.ReadChunks(afterburnerMap.Entries, HandleChunk);
                }
            }
            else if (Metadata.Codec == CodecKind.MV93)
            {
                var imapChunk = ChunkItem.Read(_input) as InitialMapChunk;
                Version = imapChunk.Version;

                foreach (int offset in imapChunk.MemoryMapOffsets)
                {
                    _input.Position = offset;
                    if (ChunkItem.Read(_input) is MemoryMapChunk mmapChunk)
                    {
                        foreach (ChunkEntry entry in mmapChunk.Entries)
                        {
                            if (entry.Flags.HasFlag(ChunkEntryFlags.Ignore))
                            {
                                HandleChunk(new UnknownChunk(_input, entry.Header)); //TODO:
                                continue;
                            }
                            _input.Position = entry.Offset;

                            ChunkItem chunk = ChunkItem.Read(_input);
                            chunk.Header.Id = entry.Header.Id;
                            HandleChunk(chunk);
                        }
                    }
                }
            }
        }
예제 #2
0
        public void Disassemble()
        {
            var input = new ShockwaveReader(_input.Span, Metadata.IsBigEndian);

            input.Advance(Metadata.Header.GetBodySize() + Metadata.GetBodySize());

            if (Metadata.Codec == CodecKind.FGDM ||
                Metadata.Codec == CodecKind.FGDC)
            {
                if (ChunkItem.Read(ref input) is FileVersionChunk version &&
                    ChunkItem.Read(ref input) is FileCompressionTypesChunk compressionTypes &&
                    ChunkItem.Read(ref input) is AfterburnerMapChunk afterburnerMap &&
                    ChunkItem.Read(ref input) is FileGzipEmbeddedImageChunk fgei)
                {
                    Chunks = fgei.ReadChunks(ref input, afterburnerMap.Entries);
                }
            }
            else if (Metadata.Codec == CodecKind.MV93)
            {
                var imapChunk = ChunkItem.Read(ref input) as InitialMapChunk;
                Version = imapChunk.Version;

                foreach (int offset in imapChunk.MemoryMapOffsets)
                {
                    input.Position = offset;
                    if (ChunkItem.Read(ref input) is MemoryMapChunk mmapChunk)
                    {
                        foreach (ChunkEntry entry in mmapChunk.Entries)
                        {
                            if (entry.Header.Kind == ChunkKind.RIFX)
                            {
                                continue;                                      //TODO: HACK
                            }
                            if (entry.Flags.HasFlag(ChunkEntryFlags.Ignore))
                            {
                                Chunks.Add(entry.Id, new UnknownChunk(ref input, entry.Header));
                                continue;
                            }

                            input.Position = entry.Offset;
                            Chunks.Add(entry.Id, ChunkItem.Read(ref input));
                        }
                    }
                }
            }

            //TODO:
            _input = null;
        }
예제 #3
0
        public unsafe ChunkItem ReadCompressedChunk(AfterBurnerMapEntry entry)
        {
            Span <byte> decompressedData = entry.DecompressedLength <= 1024 ?
                                           stackalloc byte[entry.DecompressedLength] : new byte[entry.DecompressedLength];

            fixed(byte *pBuffer = &_data.Slice(Position + 2)[0])  //Skip ZLib header
            {
                using var stream        = new UnmanagedMemoryStream(pBuffer, entry.Length - 2);
                using var deflateStream = new DeflateStream(stream, CompressionMode.Decompress);

                deflateStream.Read(decompressedData);
            }

            Advance(entry.Length);

            ShockwaveReader input = new ShockwaveReader(decompressedData, IsBigEndian);

            return(ChunkItem.Read(ref input, entry.Header));
        }