Example #1
0
        public static string Header(ZHeader header, int col1Width = 25)
        {
            var h = header;

            var pairs = new Dictionary <string, string>
            {
                { "ZMachine Version", $"{h.Version}" },
                { "Flags1", Flags((byte)h.Flags1) },
                { "Flags2", Flags(h.Flags2) },
                { "Abbreviations Table", Word(h.AbbreviationsTable) },
                { "Object Table", Word(h.ObjectTable) },
                { "Globals", Word(h.Globals) },
                { "Dynamic Memory Size", Word(h.DynamicMemorySize) },
                { "Static Memory", Word(h.StaticMemoryBaseAddress) },
                { "Dictionary", Word(h.Dictionary) },
                { "High Memory", Word(h.HighMemoryBaseAddress) },
                { "Program Counter:", Word(h.ProgramCounter) },
                { "Unknown1 (0x01):", Byte(h.Unknown1) },
                { "Unknown2 (0x12):", Word(h.Unknown2) },
                { "Unknown3 (0x14):", Word(h.Unknown3) },
                { "Unknown4 (0x16):", Word(h.Unknown4) }
            };

            return(KeyValues(pairs));
        }
Example #2
0
        public BlorbFile(Stream stream)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            this.memory = stream.ReadFully();

            var reader = new MemoryReader(this.memory, 0);

            var dwords = reader.NextDWords(3);

            // First, ensure that this is a valid format
            if (dwords[0] != id_FORM)
            {
                throw new InvalidOperationException();
            }

            if (dwords[2] != id_IFRS)
            {
                throw new InvalidOperationException();
            }

            int totalLength = (int)dwords[1] + 8;

            // Collect all chunks
            this.chunks = new List <ChunkDescriptor>();

            while (reader.Address < totalLength)
            {
                var chunk = new ChunkDescriptor();

                chunk.Address = (uint)reader.Address;

                var type = reader.NextDWord();
                var len  = reader.NextDWord();

                chunk.Type = type;
                if (type == id_FORM)
                {
                    chunk.DataAddress = chunk.Address;
                    chunk.Length      = len + 8;
                }
                else
                {
                    chunk.DataAddress = (uint)reader.Address;
                    chunk.Length      = len;
                }

                chunks.Add(chunk);

                reader.Skip((int)len);
                if ((reader.Address & 1) != 0)
                {
                    reader.Skip(1);
                }

                if (reader.Address > totalLength)
                {
                    throw new InvalidOperationException();
                }
            }

            // Loop through chunks and collect resources
            this.resources = new List <ResourceDecriptor>();

            foreach (var chunk in chunks)
            {
                if (chunk.Type == id_RIdx)
                {
                    reader.Address = (int)chunk.DataAddress;
                    var numResources = (int)reader.NextDWord();

                    if (chunk.Length < (numResources * 12) + 4)
                    {
                        throw new InvalidOperationException();
                    }

                    for (int i = 0; i < numResources; i++)
                    {
                        var resource = new ResourceDecriptor();
                        resource.Usage  = reader.NextDWord();
                        resource.Number = reader.NextDWord();

                        var resourcePos = reader.NextDWord();

                        var chunkIndex = chunks.FindIndex(c => c.Address == resourcePos);
                        if (chunkIndex < 0)
                        {
                            throw new InvalidOperationException();
                        }

                        resource.ChunkNumber = chunkIndex;

                        resources.Add(resource);
                    }
                }
                else if (chunk.Type == id_RelN)
                {
                    reader.Address = (int)chunk.DataAddress;
                    if (chunk.Length < 2)
                    {
                        throw new InvalidOperationException();
                    }

                    releaseNumber = reader.NextWord();
                }
                else if (chunk.Type == id_IFhd)
                {
                    reader.Address = (int)chunk.DataAddress;
                    if (chunk.Length < 3)
                    {
                        throw new InvalidOperationException();
                    }

                    var header = new ZHeader();
                    header.ReleaseNumber = reader.NextWord();
                    header.SerialNumber  = new char[6];
                    for (int i = 0; i < 6; i++)
                    {
                        header.SerialNumber[i] = (char)reader.NextByte();
                    }
                    header.Checksum = reader.NextWord();
                }
                else if (chunk.Type == id_Reso)
                {
                }
                else if (chunk.Type == id_Loop)
                {
                }
                else if (chunk.Type == id_Plte)
                {
                }
            }
        }