Exemplo n.º 1
0
 public TagWrapper(TagBlock tag, MapStream map, Tag meta)
 {
     tag_ = tag;
     /* Enumerate through all the StringIDs in this tag, check to see if they exist in the Globals list,
      * if not we should add them locally and update the StringID value to point to the list*/
     foreach (StringID string_id in tag as IEnumerable<StringID>)
     {
         if (Halo2.Strings.Contains(string_id)) continue;
         else
         {
             var string_value = map.Strings[string_id.Index];
             var entry = new KeyValuePair<StringID, string>(string_id, string_value);
             local_strings_.Add(entry);
             var index = local_strings_.IndexOf(entry);
             short string_id_index = (short)(index |= 0x8000);
             sbyte string_length = (sbyte)Encoding.UTF8.GetByteCount(string_value);
             var bytes = BitConverter.GetBytes((int)new StringID(string_id_index, string_length));
             (string_id as IField).SetFieldData(bytes);
         }
     }
     foreach (TagIdentifier tag_id in tag as IEnumerable<TagIdentifier>)
     {
         tag_ids_.Add(tag_id);
     }
     /*Intent: to build a list of all tagblock addresses in tag
      */
     foreach (var array in tag as IEnumerable<IFieldArray>)
     {
         var address = array.Address;
         if (array.Fields.Count() > 0)
         {
             var item = new { Address = address, Size = array.Fields[0].Size, Count = array.Fields.Count() };
             tag_blocks.Add(item);
             if (meta.Contains(item.Address))
             {
             }
         }
     }
     /* Intent: check every tag_block in the list for being external
      * if it is external build a reference list and add information about the tag_block
      * to that list.
      * address => [count, size]?
      * */
 }
Exemplo n.º 2
0
 //public void SerializeTag(tag_info meta)
 //{
 //    string name = Paths[meta.Id.Index];
 //    TagBlock block = Halo2.CreateInstance(meta.Type);
 //    (block as IPointable).Address = meta.VirtualAddress;
 //    Memory memory = GetTagMemory(meta);
 //    (block as IPointable).Parse(memory);
 //    for (int i = 0; i < memory.instance_table.Count; ++i)
 //    {
 //        if (memory.instance_table[i].external && !memory.instance_table[i].isnull)
 //        {
 //            throw new Exception(":D \n\n\n\n\n");
 //        }
 //    }
 //    MemoryStream raw_data = new MemoryStream();
 //    if (meta.Type == (tag_class)"bitm")
 //    {
 //        Bitmap_Collection collection = (Bitmap_Collection)block;
 //        foreach (var bitmap in collection.Bitmaps)
 //        {
 //            var resource = bitmap.get_resource();
 //            BinaryReader bin_reader = new BinaryReader(this);
 //            bin_reader.BaseStream.Position = resource.offset0;
 //            raw_data.Write(bin_reader.ReadBytes(resource.length0), 0, resource.length0);
 //        }
 //    }
 //    //if (meta.Type == (tag_class)"mode")
 //    //{
 //    //    model collection = (model)block;
 //    //    foreach (var bitmap in collection.Sections)
 //    //    {
 //    //        var resource = bitmap.GetRawPointer();
 //    //        BinaryReader bin_reader = new BinaryReader(this);
 //    //        bin_reader.BaseStream.Position = resource.Address;
 //    //        raw_data.Write(bin_reader.ReadBytes(resource.Length), 0, resource.Length);
 //    //        {//because
 //    //            {//f**k you
 //    //                Mesh mesh = new Mesh();
 //    //                mesh.Load(raw_data.ToArray(), bitmap.GetSectionResources(), collection.GetBoundingBox().GetCompressionRanges());
 //    //                //mesh.ExportAsWavefront(@"D:\halo_2\wavefront.obj");
 //    //            }
 //    //        }
 //    //    }
 //    //}
 //    memory = memory.Copy(16);//setup for local
 //    using (FileStream output = File.Create(@"D:\halo_2\shad.bin"))
 //    {
 //        BinaryWriter binary_writer = new BinaryWriter(output);
 //        binary_writer.Write((int)meta.Type);
 //        binary_writer.Write((int)meta.Id);
 //        binary_writer.Write((int)(Padding.GetCount(memory.Length) + memory.Length));
 //        binary_writer.Write((int)raw_data.Length);
 //        binary_writer.Write(memory.ToArray());
 //        binary_writer.Write(new byte[Padding.GetCount(output.Position)]);
 //        binary_writer.Write(raw_data.ToArray());
 //        binary_writer.Write(new byte[Padding.GetCount(output.Position)]);
 //    }
 //}
 Memory GetTagMemory(Tag meta)
 {
     //BinaryReader bin_reader = new BinaryReader(this);
     //this.Position = meta.VirtualAddress;
     //Memory mem = new Memory(bin_reader.ReadBytes(meta.Length), meta.VirtualAddress);
     //TagBlock block = Halo2.CreateInstance(meta.Type);
     //mem.instance_table.Add(new Memory.mem_ref() { address = meta.VirtualAddress, client = block, count = 1, external = false, type = block.GetType() });
     //(block as IPointable).Address = meta.VirtualAddress;
     //(block as IPointable).Parse(mem);
     //return mem;
     return new Memory ();
 }
Exemplo n.º 3
0
 TagBlock GetTag(Tag tag)
 {
     TagBlock block = Halo2.CreateInstance(tag.Type);
     block.SetAddress(tag.VirtualAddress);
     block.Parse(this);
     return block;
 }
Exemplo n.º 4
0
 public IMap this[TagIdentifier tag_id]
 {
     get
     {
         if (current_tag.Identifier == tag_id) return this;
         current_tag = Tags[tag_id.Index];
         return this;
     }
 }
Exemplo n.º 5
0
 public IMap this[string tag_class, string tag_name]
 {
     get
     {
         if (current_tag.Type == (TagClass)tag_class && current_tag.Path.Contains(tag_name)) return this;
         current_tag = FindFirst((TagClass)tag_class, tag_name);
         return this;
     }
 }
Exemplo n.º 6
0
        public MapStream(string filename)
            : base(filename, FileMode.Open, FileAccess.Read, FileShare.Read)
        {
            this.MemoryBlocks = new MemoryMappedAddress[2];
            //HEADER
            BinaryReader bin = new BinaryReader(this, Encoding.UTF8);

            this.Lock(0, 2048);
            this.Seek(0, SeekOrigin.Begin);
            if (bin.ReadTagClass() != (TagClass)"head")
                throw new InvalidDataException("Not a halo-map file");

            //this.Seek(36, SeekOrigin.Begin);
            //var version = bin.ReadInt32();
            //switch (version)
            //{
            //    case 0:
            //        BuildVersion = Version.XBOX_RETAIL;
            //        break;
            //    case -1:
            //        BuildVersion = Version.PC_RETAIL;
            //        break;
            //    default:
            //}
            BuildVersion = Version.PC_RETAIL;
            this.Seek(16, SeekOrigin.Begin);

            int indexAddress = bin.ReadInt32();
            int indexLength = bin.ReadInt32();
            int tagCacheLength = bin.ReadInt32();

            if (BuildVersion == Version.PC_RETAIL)
                this.Seek(12, SeekOrigin.Current);

            this.Seek(332, SeekOrigin.Current);

            int stringTableLength = bin.ReadInt32();
            this.Seek(4, SeekOrigin.Current);
            int stringTableAddress = bin.ReadInt32();

            this.Seek(36, SeekOrigin.Current);

            MapName = bin.ReadFixedString(32);

            this.Seek(4, SeekOrigin.Current);

            Scenario = bin.ReadFixedString(256);

            this.Seek(4, SeekOrigin.Current);
            int pathsCount = bin.ReadInt32();
            int pathsTableAddress = bin.ReadInt32();
            int pathsTableLength = bin.ReadInt32();

            this.Unlock(0, 2048);

            this.Seek(pathsTableAddress, SeekOrigin.Begin);
            var Paths = Encoding.UTF8.GetString(bin.ReadBytes(pathsTableLength - 1)).Split(char.MinValue);

            //STRINGS

            this.Seek(stringTableAddress, SeekOrigin.Begin);
            Strings = Encoding.UTF8.GetString(bin.ReadBytes(stringTableLength - 1)).Split(char.MinValue);

            //  INDEX
            /*
             *  Vista doesn't use memory addresses for the following address-values. (they are instead 0-based from the index-address)
             *
             *  0x00    Address to Classes array
             *  0x04    Classes array length
             *  0x08    Address to Tags array
             *  0x0C    Scenario        tag_id
             *  0x10    Match-Globals   tag_id
             *  0x14    ~
             *  0x18    Tags array length
             *  0xC0    'sgat'          four_cc
             *
             *  */
            this.Seek(indexAddress, SeekOrigin.Begin);
            int tagClassTableVirtualAddress = bin.ReadInt32();
            this.IndexVirtualAddress = tagClassTableVirtualAddress - 32;
            this.Seek(4, SeekOrigin.Current);
            int tagDatumTableVirtualAddress = bin.ReadInt32();
            var ScenarioID = bin.ReadTagID();
            var GlobalsID = bin.ReadTagID();
            int tagDatumTableOffset = tagDatumTableVirtualAddress - tagClassTableVirtualAddress;
            this.Seek(4, SeekOrigin.Current);
            int tagDatumCount = bin.ReadInt32();

            this.Seek(4 + tagDatumTableOffset, SeekOrigin.Current);
            Tags = new Tag[tagDatumCount];
            for (int i = 0; i < tagDatumCount; i++)
            {
                Tags[i] = new Tag()
                {
                    Type = bin.ReadTagType(),
                    Identifier = bin.ReadInt32(),
                    VirtualAddress = bin.ReadInt32(),
                    Length = bin.ReadInt32()
                };
                if (i == 0)
                {
                    SecondaryMagic = Tags[0].VirtualAddress - (indexAddress + indexLength);
                }

                //Borky vista fix - broken paths are broken
                //if (Tags[i].VirtualAddress == 0) continue;
                //var tag = Tags[i];
                //Tags[i].Path = Paths[Tags[i].Identifier.SaltedIndex];
            }

            this.MemoryBlocks[1] = new MemoryMappedAddress()
            {
                Address = Tags[0].VirtualAddress,
                Length = tagCacheLength,
                Magic = SecondaryMagic,
            };

            /* Intent: read the sbsp and lightmap address and lengths from the scenario tag
             * and store them in the Tags array.
             */
            if (BuildVersion == Version.XBOX_RETAIL)
            {
                this.Seek(Tags[ScenarioID.Index].VirtualAddress - SecondaryMagic + 528, SeekOrigin.Begin);
                var count = bin.ReadInt32();
                var address = bin.ReadInt32();
                for (int i = 0; i < count; ++i)
                {
                    this.Seek(address - SecondaryMagic + i * 68, SeekOrigin.Begin);
                    var sbsp_offset = bin.ReadInt32();
                    var sbsp_length = bin.ReadInt32();
                    var sbsp_virtual_address = bin.ReadInt32();
                    if (i == 0)
                    {
                        this.PrimaryMagic = sbsp_virtual_address - sbsp_offset;
                        this.MemoryBlocks[0].Address = sbsp_virtual_address;
                        this.MemoryBlocks[0].Magic = this.PrimaryMagic;
                    }
                    this.MemoryBlocks[0].Length += sbsp_length;

                    Seek(8, SeekOrigin.Current);
                    var sbsp_identifier = bin.ReadTagID();
                    Seek(4, SeekOrigin.Current);
                    var ltmp_identifier = bin.ReadTagID();

                    var ltmp_offset = bin.ReadInt32();
                    var ltmp_length = sbsp_offset + sbsp_length - ltmp_offset;

                    Tags[sbsp_identifier.Index].VirtualAddress = sbsp_virtual_address;
                    Tags[sbsp_identifier.Index].Length = sbsp_length - ltmp_length;

                    if (ltmp_identifier != TagIdentifier.null_identifier)
                    {
                        Tags[ltmp_identifier.Index].VirtualAddress = sbsp_virtual_address + ltmp_offset;
                        Tags[ltmp_identifier.Index].Length = ltmp_length;
                    }
                }

                //UNICODE
                this.Seek(Tags[GlobalsID.Index].VirtualAddress - SecondaryMagic + 400, SeekOrigin.Begin);
                int unicodeCount = bin.ReadInt32();
                int unicodeTableLength = bin.ReadInt32();
                int unicodeIndexAddress = bin.ReadInt32();
                int unicodeTableAddress = bin.ReadInt32();

                Unicode = new UnicodeValueNamePair[unicodeCount];

                StringID[] strRefs = new StringID[unicodeCount];
                int[] strOffsets = new int[unicodeCount];

                this.Seek(unicodeIndexAddress, SeekOrigin.Begin);
                for (int i = 0; i < unicodeCount; i++)
                {
                    strRefs[i] = (StringID)bin.ReadInt32();
                    strOffsets[i] = bin.ReadInt32();
                }
                for (int i = 0; i < unicodeCount; i++)
                {
                    this.Seek(unicodeTableAddress + strOffsets[i], SeekOrigin.Begin);
                    StringBuilder unicodeString = new StringBuilder(byte.MaxValue);
                    while (bin.PeekChar() != char.MinValue)
                        unicodeString.Append(bin.ReadChar());
                    Unicode[i] = new UnicodeValueNamePair { Name = strRefs[i], Value = unicodeString.ToString() };
                }
            }
        }