예제 #1
0
        /// <summary>
        /// Serializes a tag reference.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="writer">The writer to write to.</param>
        /// <param name="referencedTag">The referenced tag.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        private void SerializeTagReference(ISerializationContext context, BinaryWriter writer, CachedTagInstance referencedTag, TagFieldAttribute valueInfo)
        {
            if ((referencedTag?.Index ?? 0) == -1)
            {
                referencedTag = context.GetTagByName(referencedTag.Group, referencedTag.Name);
            }

            if (referencedTag != null && valueInfo != null && valueInfo.ValidTags != null)
            {
                foreach (string tag in valueInfo.ValidTags)
                {
                    if (!referencedTag.IsInGroup(tag))
                    {
                        throw new Exception($"Invalid group for tag reference: {referencedTag.Group.Tag}");
                    }
                }
            }

            if (valueInfo == null || !valueInfo.Flags.HasFlag(TagFieldFlags.Short))
            {
                writer.Write((referencedTag != null) ? referencedTag.Group.Tag.Value : -1);
                writer.Write(0);
                writer.Write(0);
            }
            writer.Write((referencedTag != null) ? referencedTag.Index : -1);
        }
예제 #2
0
        public override object Execute(List <string> args)
        {
            //Arguments needed: filepath, <new>|<tagIndex>
            if (args.Count < 2)
            {
                return(false);
            }

            CachedTagInstance tag = null;
            bool b_duplicate;

            // optional argument: forces overwriting of tags that are not type: coll
            var b_force = (args.Count >= 3 && args[2].ToLower().Equals("force"));

            if (args[1].ToLower().Equals("new"))
            {
                b_duplicate = true;
            }
            else
            {
                if (!CacheContext.TryGetTag(args[1], out tag))
                {
                    return(false);
                }

                b_duplicate = false;
            }

            if (!b_force && !b_duplicate && !tag.IsInGroup("coll"))
            {
                Console.WriteLine("Tag to override was not of class- 'coll'. Use third argument- 'force' to inject into this tag.");
                return(false);
            }

            string filepath = args[0];

            string[]       fpaths       = null;
            CollisionModel coll         = null;
            bool           b_singleFile = Path.GetExtension(filepath).Equals(".model_collision_geometry") &&
                                          !Directory.Exists(filepath);

            var modelbuilder = new CollisionGeometryBuilder();
            int n_objects    = 1;

            if (!b_singleFile)
            {
                fpaths = Directory.GetFiles(filepath, "*.model_collision_geometry");

                if (fpaths.Length == 0)
                {
                    Console.WriteLine("No Halo 1 coll tags in directory: \"{0}\"", filepath);
                    return(false);
                }

                filepath  = fpaths[0];
                n_objects = fpaths.Length;
            }

            Console.WriteLine(
                (n_objects == 1 ? "Loading coll tag..." : "Loading coll tags..."), n_objects);

            if (!modelbuilder.ParseFromFile(filepath))
            {
                return(false);
            }

            coll = modelbuilder.Build();

            if (coll == null)
            {
                Console.WriteLine("Builder produced null result.");
                return(false);
            }

            if (!b_singleFile)
            {
                for (int i = 1; i < fpaths.Length; ++i)
                {
                    if (!modelbuilder.ParseFromFile(fpaths[i]))
                    {
                        return(false);
                    }

                    var coll2 = modelbuilder.Build();

                    if (coll2 == null)
                    {
                        Console.WriteLine("Builder produced null result.");
                        return(false);
                    }

                    coll.Regions.Add(coll2.Regions[0]);
                }
            }

            using (var stream = CacheContext.OpenTagCacheReadWrite())
            {
                if (b_duplicate)
                {
                    //duplicate an existing tag, trashcan phmo
                    tag = CacheContext.TagCache.DuplicateTag(stream, CacheContext.TagCache.Index[0x4436]);
                    if (tag == null)
                    {
                        Console.WriteLine("Failed tag duplication.");
                        return(false);
                    }
                }

                CacheContext.Serialize(stream, tag, coll);
            }

            Console.WriteLine(n_objects == 1 ? "Added 1 collision." : "Added {0} collisions in one tag.", n_objects);
            Console.Write("Successfully imported coll to: ");
            TagPrinter.PrintTagShort(tag);

            return(true);
        }
        public override object Execute(List <string> args)
        {
            //Arguments needed: filepath, <new>|<tagIndex>
            if (args.Count < 2)
            {
                return(false);
            }

            CachedTagInstance tag = null;
            bool b_duplicate;
            // optional argument: forces overwriting of tags that are not type: phmo
            bool b_force = (args.Count >= 3 && args[2].ToLower().Equals("force"));

            if (args[1].ToLower().Equals("new"))
            {
                b_duplicate = true;
            }
            else
            {
                if (!CacheContext.TryGetTag(args[1], out tag))
                {
                    return(false);
                }

                b_duplicate = false;
            }

            if (!b_force && !b_duplicate && !tag.IsInGroup("phmo"))
            {
                Console.WriteLine("Tag to override was not of class- 'phmo'. Use third argument- 'force' to inject.");
                return(false);
            }

            var filename = args[0];

            var modelbuilder = new PhysicsModelBuilder();

            if (!modelbuilder.ParseFromFile(filename))
            {
                return(false);
            }
            //modelbuilder must also make a node for the physics model
            var phmo = modelbuilder.Build();

            if (phmo == null)
            {
                return(false);
            }

            using (var stream = CacheContext.OpenTagCacheReadWrite())
            {
                if (b_duplicate)
                {
                    //duplicate an existing tag, trashcan phmo
                    tag = CacheContext.TagCache.DuplicateTag(stream, CacheContext.TagCache.Index[0x4436]);
                    if (tag == null)
                    {
                        Console.WriteLine("Failed tag duplication.");
                        return(false);
                    }
                }

                CacheContext.Serialize(stream, tag, phmo);
            }

            Console.Write("Successfully imported phmo to: ");

            TagPrinter.PrintTagShort(tag);

            return(true);
        }
예제 #4
0
        public void LoadTagEditor(CachedTagInstance tag)
        {
            if (tag == null || (CurrentTag != null && CurrentTag.Index == tag.Index))
            {
                return;
            }

            LoadingTag = true;

            object definition = null;

            if (CurrentTags.ContainsKey(tag.Index))
            {
                definition = CurrentTags[tag.Index];
            }

            tagTreeView.Enabled = false;

            tagEditorPanel.Controls.Clear();

            var tagName = tag.Name ?? $"0x{tag.Index:X4}";

            var groupName = CacheContext.GetString(tag.Group.Name);

            statusLabel.Text = $"Loading {tagName}.{ groupName}...";

            progressBar.Style = ProgressBarStyle.Marquee;
            progressBar.MarqueeAnimationSpeed = 30;

            if (definition == null)
            {
                using (var stream = CacheContext.OpenTagCacheRead())
                    definition = CacheContext.Deserializer.Deserialize(
                        new TagSerializationContext(stream, CacheContext, tag),
                        TagDefinition.Find(tag.Group.Tag));
            }

            if (tagName.Contains("\\"))
            {
                var index = tagName.LastIndexOf('\\') + 1;
                tagName = tagName.Substring(index, tagName.Length - index);
            }

            statusLabel.Text = $"Generating {groupName} interface...";
            Application.DoEvents();

            var point = new Point();

            if (tag.IsInGroup("matg") || tag.IsInGroup("mulg") || tag.IsInGroup("scnr") || tag.IsInGroup("sbsp"))
            {
                var control = new StructMultiControl(this, CacheContext, tag, definition)
                {
                    Dock = DockStyle.Fill
                };

                control.GetFieldValue(null, definition, definition);

                tagEditorPanel.Controls.Add(control);
            }
            else if (tag.IsInGroup("bitm") || tag.IsInGroup("obje"))
            {
                var splitContainer = new SplitContainer
                {
                    Dock        = DockStyle.Fill,
                    Orientation = Orientation.Horizontal
                };

                splitContainer.FixedPanel = FixedPanel.Panel1;

                tagEditorPanel.Controls.Add(splitContainer);
                splitContainer.BringToFront();

                if (tag.IsInGroup("bitm"))
                {
                    splitContainer.SplitterDistance = Math.Min((short)512, Math.Max((short)16, ((TagTool.Tags.Definitions.Bitmap)definition).Images[0].Height));
                }
                else if (tag.IsInGroup("obje"))
                {
                    splitContainer.SplitterDistance = 384;
                }

                if (tag.IsInGroup("bitm"))
                {
                    var bitmDefinition = (TagTool.Tags.Definitions.Bitmap)definition;

                    var bitmapControl = new BitmapControl(CacheContext, bitmDefinition)
                    {
                        Dock = DockStyle.Fill
                    };

                    splitContainer.Panel1.Controls.Add(bitmapControl);
                    bitmapControl.BringToFront();
                }
                else if (tag.IsInGroup("obje"))
                {
                    var modelControl = new ObjectControl(CacheContext, (GameObject)definition)
                    {
                        Dock = DockStyle.Fill
                    };

                    splitContainer.Panel1.Controls.Add(modelControl);
                    modelControl.BringToFront();
                }

                var control = tag.IsInGroup("obje") ?
                              (Control) new StructMultiControl(this, CacheContext, tag, definition)
                {
                    Dock = DockStyle.Fill
                } :
                new StructControl(this, CacheContext, definition.GetType(), null);

                ((IFieldControl)control).GetFieldValue(null, definition, definition);
                control.Location = point;

                splitContainer.Panel2.Controls.Add(control);
                splitContainer.Panel2.AutoScroll = true;
            }
            else
            {
                if (tag.IsInGroup("snd!"))
                {
                    var soundControl = new SoundControl(CacheContext, tag, (TagTool.Tags.Definitions.Sound)definition)
                    {
                        Dock = DockStyle.Top
                    };

                    tagEditorPanel.Controls.Add(soundControl);
                    soundControl.BringToFront();

                    point.Y = soundControl.Bottom;
                }

                var control = new StructControl(this, CacheContext, definition.GetType(), null);
                control.GetFieldValue(null, definition, definition);

                control.Location = point;

                tagEditorPanel.Controls.Add(control);
            }

            statusLabel.Text = "";

            progressBar.Style = ProgressBarStyle.Continuous;
            progressBar.MarqueeAnimationSpeed = 0;

            tagTreeView.Enabled = true;
            CurrentTag          = tag;

            if (!CurrentTags.ContainsKey(tag.Index))
            {
                CurrentTags[tag.Index] = definition;

                var item = new TagInstanceItem {
                    CacheContext = CacheContext, Tag = tag
                };
                currentTagsComboBox.Items.Add(item);

                currentTagsComboBox.SelectedItem = item;
            }
            else
            {
                for (var i = 0; i < currentTagsComboBox.Items.Count; i++)
                {
                    var item = (TagInstanceItem)currentTagsComboBox.Items[i];

                    if (item.Tag.Index == tag.Index)
                    {
                        currentTagsComboBox.SelectedIndex = i;
                        break;
                    }
                }
            }

            LoadingTag = false;
        }
예제 #5
0
 private string GetTagTreeNodeImageKey(CachedTagInstance tag)
 {
     if (tag.IsInGroup("cfgt") || tag.IsInGroup("matg") || tag.IsInGroup("mulg") ||
         tag.IsInGroup("aigl") || tag.IsInGroup("smdt") ||
         tag.IsInGroup("inpg") || tag.IsInGroup("rasg") ||
         tag.IsInGroup("wezr") || tag.IsInGroup("wgtz") || tag.IsInGroup("wigl"))
     {
         return("file_settings");
     }
     if (tag.IsInGroup("jmad"))
     {
         return("file_animation");
     }
     else if (tag.IsInGroup("bitm"))
     {
         return("file_bitmap");
     }
     else if (tag.IsInGroup("snd!") || tag.IsInGroup("lsnd"))
     {
         return("file_sound");
     }
     else
     {
         return("file");
     }
 }
예제 #6
0
        private CachedTagInstance ConvertTag(CachedTagInstance srcTag, HaloOnlineCacheContext srcCacheContext, Stream srcStream, HaloOnlineCacheContext destCacheContext, Stream destStream, TagVersionMap tagMap)
        {
            TagPrinter.PrintTagShort(srcTag);

            // Uncomment this to use 0x101F for all shaders

            /*if (srcTag.IsClass("rm  "))
             *  return destCacheContext.Cache.Tags[0x101F];*/

            // Check if the tag is in the map, and just return the translated tag if so
            var destIndex = tagMap.Translate(srcCacheContext.Version, srcTag.Index, destCacheContext.Version);

            if (destIndex >= 0)
            {
                Console.WriteLine("- Using already-known index {0:X4}", destIndex);
                return(destCacheContext.TagCache.Index[destIndex]);
            }

            // Deserialize the tag from the source cache
            var tagData = srcCacheContext.Deserialize(srcStream, srcTag);

            // Uncomment this to use 0x101F in place of shaders that need conversion

            /*if (tagData is RenderMethod)
             * {
             *  var rm = (RenderMethod)tagData;
             *  foreach (var prop in rm.ShaderProperties)
             *  {
             *      if (tagMap.Translate(srcCacheContext.Version, prop.Template.Index, destCacheContext.Version) < 0)
             *          return destCacheContext.Cache.Tags[0x101F];
             *  }
             * }*/

            // Allocate a new tag and create a mapping for it

            CachedTagInstance instance = null;

            if (srcCacheContext.Version != destCacheContext.Version)
            {
                for (var i = 0; i < destCacheContext.TagCache.Index.Count; i++)
                {
                    if (destCacheContext.TagCache.Index[i] == null)
                    {
                        destCacheContext.TagCache.Index[i] = instance = new CachedTagInstance(i, TagGroup.Instances[srcTag.Group.Tag]);
                        break;
                    }
                }
            }
            else
            {
                if (destCacheContext.TagCache.Index[srcTag.Index] != null)
                {
                    if (destCacheContext.TagCache.Index[srcTag.Index].IsInGroup(srcTag.Group))
                    {
                        return(destCacheContext.TagCache.Index[srcTag.Index]);
                    }
                }
                else
                {
                    destCacheContext.TagCache.Index[srcTag.Index] = instance = new CachedTagInstance(srcTag.Index, TagGroup.Instances[srcTag.Group.Tag], srcTag.Name);
                }
            }

            if (instance == null)
            {
                instance = destCacheContext.TagCache.AllocateTag(srcTag.Group);
            }

            tagMap.Add(srcCacheContext.Version, srcTag.Index, destCacheContext.Version, instance.Index);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                IsDecalShader = true;
            }

            // Convert it
            tagData = Convert(tagData, srcCacheContext, srcStream, destCacheContext, destStream, tagMap);

            if (srcTag.IsInGroup("decs") || srcTag.IsInGroup("rmd "))
            {
                IsDecalShader = false;
            }

            // Re-serialize into the destination cache
            destCacheContext.Serialize(destStream, instance, tagData);
            return(instance);
        }