Esempio n. 1
0
        public void CreateTagLayout(GuerillaReader reader, MutationCodeScope parentScope)
        {
            // Our child code creator for the tag group/block.
            MutationCodeCreator childCodeCreator = null;

            // Check if this tag block is a tag group.
            if (this.TagBlockDefinition.IsTagGroup == true)
            {
                // Get the tag group that points to this tag block definition.
                tag_group tagGroup = reader.TagGroups.First(tag => tag.definition_address == this.TagBlockDefinition.s_tag_block_definition.address);

                // Compute the size of the definition.
                int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagGroup.Definition.TagFields[tagGroup.Definition.GetFieldSetIndexClosestToH2Xbox()]);

                // Check if the tag group has a parent tag group it inherits from.
                if (tagGroup.ParentGroupTag != string.Empty)
                {
                    // Get the parent tag group object.
                    tag_group parentTagGroup = reader.TagGroups.First(tag => tag.GroupTag.Equals(tagGroup.ParentGroupTag) == true);

                    // Now find the code scope for the parent tag layout.
                    MutationCodeScope parentTagScope = parentScope.Types.Values.First(scope => scope.DefinitionAddress == parentTagGroup.definition_address);

                    // Create a new tag group class.
                    childCodeCreator = this.CodeCreator.CreateTagGroupClass(this.TypeName,
                                                                            TagGroupDefinitionAttribute.CreateAttributeDeclaration(tagGroup, definitionSize), parentTagScope.Namespace);
                }
                else
                {
                    // Create a new tag group class.
                    childCodeCreator = this.CodeCreator.CreateTagGroupClass(this.TypeName, TagGroupDefinitionAttribute.CreateAttributeDeclaration(tagGroup, definitionSize));
                }
            }
            else
            {
                // Compute the size of the definition.
                int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, this.TagBlockDefinition.TagFields[this.TagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]);

                // Create a new tag block class.
                childCodeCreator = this.CodeCreator.CreateTagBlockClass(this.TypeName, TagBlockDefinitionAttribute.CreateAttributeDeclaration(this.TagBlockDefinition, definitionSize));
            }

            // Process the tag block definition.
            ProcessTagBlockDefinition(reader, this.TagBlockDefinition, childCodeCreator, this.CodeScope, parentScope);
        }
Esempio n. 2
0
        private void ProcessFields(List <tag_field> fields, GuerillaReader reader, MutationCodeCreator blockCodeCreator,
                                   MutationCodeScope blockCodeScope, MutationCodeScope parentScope)
        {
            // Loop through all of the fields in the collection.
            for (int i = 0; i < fields.Count; i++)
            {
                // Create a new field and add it to the scope for this block.
                string            displayName, units, tooltip;
                EditorMarkUpFlags markupFlags;
                string            fieldName = blockCodeScope.CreateCodeSafeFieldName(fields[i].type, fields[i].Name, out displayName, out units, out tooltip, out markupFlags);

                // Create an attribute collection for any attributes we might add to the field.
                CodeAttributeDeclarationCollection attributeCollection = new CodeAttributeDeclarationCollection();

                // Make sure at least one of the required fields for a UI markup attribute is valid.
                if (markupFlags != EditorMarkUpFlags.None || displayName != string.Empty || units != string.Empty || tooltip != string.Empty)
                {
                    // Create the UI markup attribute using the information provided.
                    attributeCollection.Add(EditorMarkUpAttribute.CreateAttributeDeclaration(flags: markupFlags, displayName: displayName, unitsSpecifier: units, tooltipText: tooltip));
                }

                // Handle each field accordingly.
                switch (fields[i].type)
                {
                case field_type._field_char_enum:
                case field_type._field_enum:
                case field_type._field_long_enum:
                {
                    // Cast the field to a enum_definition struct.
                    enum_definition enumDefinition = (enum_definition)fields[i];

                    // Check if there is an existing code scope for this enum type.
                    MutationCodeScope enumScope = blockCodeScope.FindExistingCodeScope(enumDefinition.definition_address);
                    if (enumScope == null)
                    {
                        // Create a new code scope for the enum type.
                        enumScope = blockCodeScope.CreateCodeScopeForType(enumDefinition.Name, enumDefinition.definition_address, MutationCodeScopeType.Enum);

                        // Create a new enum in the block definition for this field.
                        blockCodeCreator.AddEnumOrBitmask(enumScope, enumDefinition);
                    }

                    // Add a field to the block definition for this enum type.
                    blockCodeCreator.AddCustomTypedField(fields[i].type, fieldName, enumScope.Namespace, attributeCollection);
                    break;
                }

                case field_type._field_byte_flags:
                case field_type._field_word_flags:
                case field_type._field_long_flags:
                {
                    // Cast the field to a enum_definition struct.
                    enum_definition enumDefinition = (enum_definition)fields[i];

                    // Check if there is an existing code scope for this bitmask type.
                    MutationCodeScope bitmaskScope = blockCodeScope.FindExistingCodeScope(enumDefinition.definition_address);
                    if (bitmaskScope == null)
                    {
                        // Create a new code scope for the bitmask type.
                        bitmaskScope = blockCodeScope.CreateCodeScopeForType(enumDefinition.Name, enumDefinition.definition_address, MutationCodeScopeType.Bitmask);

                        // Create a new bitmask in the block definition for this field.
                        blockCodeCreator.AddEnumOrBitmask(bitmaskScope, enumDefinition);
                    }

                    // Add a field to the block definition for this bitmask type.
                    blockCodeCreator.AddCustomTypedField(fields[i].type, fieldName, bitmaskScope.Namespace, attributeCollection);
                    break;
                }

                case field_type._field_block:
                {
                    // Get the definition struct from the field address.
                    TagBlockDefinition tagBlockDefinition = reader.TagBlockDefinitions[fields[i].definition_address];

                    // Check if the tag block definition already exists in the parent code scope.
                    MutationCodeScope tagBlockScope = parentScope.FindExistingCodeScope(tagBlockDefinition.s_tag_block_definition.address);
                    if (tagBlockScope == null)
                    {
                        // Create a new code scope for the tag block definition.
                        tagBlockScope = parentScope.CreateCodeScopeForType(tagBlockDefinition.s_tag_block_definition.Name,
                                                                           tagBlockDefinition.s_tag_block_definition.address, MutationCodeScopeType.TagBlock);

                        // Compute the size of the definition.
                        int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagBlockDefinition.TagFields[tagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]);

                        // Create a new class for the tag block definition.
                        MutationCodeCreator childBlockCodeCreator = this.CodeCreator.CreateTagBlockClass(tagBlockScope.Namespace,
                                                                                                         TagBlockDefinitionAttribute.CreateAttributeDeclaration(tagBlockDefinition, definitionSize));

                        // Process the tag block definition.
                        ProcessTagBlockDefinition(reader, tagBlockDefinition, childBlockCodeCreator, tagBlockScope, parentScope);
                    }

                    // Create a field for the tag block.
                    blockCodeCreator.AddTagBlockField(fieldName, tagBlockScope.Namespace, attributeCollection);
                    break;
                }

                case field_type._field_struct:
                {
                    // Cast the field to a tag_struct_definition.
                    tag_struct_definition tagStruct = (tag_struct_definition)fields[i];

                    // Get the definition struct from the field address.
                    TagBlockDefinition tagBlockDefinition = reader.TagBlockDefinitions[tagStruct.block_definition_address];

                    // Check if the tag block definition already exists in the parent code scope.
                    MutationCodeScope tagBlockScope = parentScope.FindExistingCodeScope(tagBlockDefinition.s_tag_block_definition.address);
                    if (tagBlockScope == null)
                    {
                        // Create a new code scope for the tag block definition.
                        tagBlockScope = parentScope.CreateCodeScopeForType(tagBlockDefinition.s_tag_block_definition.Name,
                                                                           tagBlockDefinition.s_tag_block_definition.address, MutationCodeScopeType.Struct);

                        // Compute the size of the definition.
                        int definitionSize = TagLayoutValidator.ComputeMutationDefinitionSize(reader, tagBlockDefinition.TagFields[tagBlockDefinition.GetFieldSetIndexClosestToH2Xbox()]);

                        // Create a new class for the tag block definition.
                        MutationCodeCreator childBlockCodeCreator = this.CodeCreator.CreateTagBlockClass(tagBlockScope.Namespace,
                                                                                                         TagBlockDefinitionAttribute.CreateAttributeDeclaration(tagBlockDefinition, definitionSize));

                        // Process the tag block definition.
                        ProcessTagBlockDefinition(reader, tagBlockDefinition, childBlockCodeCreator, tagBlockScope, parentScope);
                    }

                    // Build the tag block definition attribute for the field.
                    attributeCollection.Add(TagStructAttribute.CreateAttributeDeclaration());

                    // Create a field for the tag block.
                    blockCodeCreator.AddCustomTypedField(field_type._field_struct, fieldName, tagBlockScope.Namespace, attributeCollection);
                    break;
                }

                case field_type._field_tag_reference:
                {
                    // Cast the field to a tag_reference_definition definition.
                    tag_reference_definition tagRegDefinition = (tag_reference_definition)fields[i];

                    // Build the tag reference attribute for the field.
                    attributeCollection.Add(TagReferenceAttribute.CreateAttributeDeclaration(tagRegDefinition));

                    // Add the field with the group tag filter attribute.
                    blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection);
                    break;
                }

                case field_type._field_pad:
                case field_type._field_skip:
                case field_type._field_useless_pad:
                {
                    // Build the padding attribute for the field.
                    attributeCollection.Add(PaddingAttribute.CreateAttributeDeclaration(fields[i].type, fields[i].definition_address));

                    // Add the field with the padding attribute.
                    blockCodeCreator.AddPaddingField(fieldName, fields[i].definition_address, attributeCollection);
                    break;
                }

                case field_type._field_explanation:
                {
                    // Cast the field to a explanation_definition.
                    explaination_definition explanation = (explaination_definition)fields[i];

                    // Create a field for the explanation block.
                    blockCodeCreator.AddExplanationField(fieldName, explanation.Name, explanation.Explaination);
                    break;
                }

                case field_type._field_array_start:
                {
                    // Build a list of fields inside of the array.
                    List <tag_field> arrayFields = CreateArrayFieldList(fields, i);

                    // Loop for the length of the array and process the fields.
                    for (int x = 0; x < fields[i].definition_address; x++)
                    {
                        // Process the array fields.
                        ProcessFields(arrayFields, reader, blockCodeCreator, blockCodeScope, parentScope);
                    }

                    // Skip the fields we just processed and the array terminator.
                    i += arrayFields.Count + 1;
                    break;
                }

                case field_type._field_data:
                {
                    // Cast the field to a tag_dat_definition.
                    tag_data_definition tagData = (tag_data_definition)fields[i];

                    // Create a tag data attribute for this field.
                    attributeCollection.Add(TagDataAttribute.CreateAttributeDeclaration(tagData));

                    // Add the field to the collection.
                    blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection);
                    break;
                }

                case field_type._field_custom: break;

                case field_type._field_terminator: break;

                default:
                {
                    // Check if the value type dictionary contains this field type.
                    if (MutationCodeCreator.ValueTypeDictionary.Keys.Contains(fields[i].type) == false)
                    {
                        break;
                    }

                    // Add the field to the collection.
                    blockCodeCreator.AddField(fields[i].type, fieldName, attributeCollection);
                    break;
                }
                }
            }
        }
Esempio n. 3
0
        public void GenerateLayouts(GuerillaReader reader, string outputFolder)
        {
            // Check if the subfolder for block definitions exists.
            if (Directory.Exists(string.Format("{0}\\BlockDefinitions", outputFolder)) == false)
            {
                // Create the subfolder for block definitions.
                Directory.CreateDirectory(string.Format("{0}\\BlockDefinitions", outputFolder));
            }

            // Loop through all of the definitions in Guerilla and verify the size of each one.
            for (int i = 0; i < reader.TagBlockDefinitions.Keys.Count; i++)
            {
                // Get the tag block definition.
                TagBlockDefinition tagBlock = reader.TagBlockDefinitions[reader.TagBlockDefinitions.Keys.ElementAt(i)];

                // Verify the definition address is correct.
                int definitionSize = TagLayoutValidator.ComputeGuerillaDefinitionSize(reader, tagBlock.TagFields[tagBlock.GetFieldSetIndexClosestToH2Xbox()]);
                if (definitionSize != tagBlock.TagFieldSets[tagBlock.GetFieldSetIndexClosestToH2Xbox()].size)
                {
                    // Print the details to the console.
                    System.Diagnostics.Debug.WriteLine(string.Format("Size mismatch on block \"{0}\" computed: {1} actual: {2}", tagBlock.s_tag_block_definition.Name,
                                                                     definitionSize, tagBlock.TagFieldSets[tagBlock.GetFieldSetIndexClosestToH2Xbox()].size));
                }
            }

            // Build a list of references for each tag block definition we have.
            Dictionary <string, List <TagBlockDefinition> > tagBlockReferences   = PreProcessTagBlockDefinitions(reader);
            Dictionary <string, List <TagBlockDefinition> > nonUniqueDefinitions = tagBlockReferences.Where(b => b.Value.Count > 1).ToDictionary(p => p.Key, p => p.Value);

            // Initialize our list of tag definitions to process with the tag groups from the guerilla reader.
            //tag_group hlmt = reader.TagGroups.First(tag => tag.GroupTag.Equals("hlmt"));
            List <TagBlockDefinition> tagBlockDefinitions = new List <TagBlockDefinition>(reader.TagBlockDefinitions.Values.Where(block => block.IsTagGroup == true));

            //tagBlockDefinitions.Add(reader.TagBlockDefinitions[hlmt.definition_address]);

            // Loop through all of the non-unique tag blocks and add them to the list of definitions to be processed.
            foreach (TagBlockDefinition definition in reader.TagBlockDefinitions.Values)
            {
                // Check if the definition name is in the non-unique block list.
                if (nonUniqueDefinitions.Keys.Contains(definition.s_tag_block_definition.Name) == true)
                {
                    // Add the definition to the list to be extracted.
                    tagBlockDefinitions.Add(definition);
                }
            }

            // Pre-process any tag layouts that need fixups.
            for (int i = 0; i < this.preProcessingFunctions.Count; i++)
            {
                // Find the tag block definition this preprocessing function is associated with.
                TagBlockDefinition tagBlock = reader.TagBlockDefinitions.Single(
                    block => block.Value.s_tag_block_definition.Name.Equals(this.preProcessingFunctions.ElementAt(i).Key) == true).Value;

                // Invoke the preprocessing method.
                this.preProcessingFunctions.ElementAt(i).Value.Invoke(null, new object[] { tagBlock });
            }

            // Create a list of layout creators for all of the definitions we will be processing.
            List <MutationTagLayoutCreator> layoutCreators = new List <MutationTagLayoutCreator>();

            // Loop through the list of tag block definitions and create a code scope for each one.
            // This will build a list of types in the global namespace which we need before we start processing layouts.
            for (int i = 0; i < tagBlockDefinitions.Count; i++)
            {
                // Create a new tag layout creator and have it create its code scope using the tag block definition.
                MutationTagLayoutCreator layoutCreator = new MutationTagLayoutCreator(tagBlockDefinitions[i]);
                layoutCreator.CreateCodeScope(this.globalCodeScope);

                // Add the layout creator to the list.
                layoutCreators.Add(layoutCreator);
            }

            // Now that we have a type list built loop through all of the layout creators and create the actual tag layouts.
            for (int i = 0; i < layoutCreators.Count; i++)
            {
                // Generate the layout.
                layoutCreators[i].CreateTagLayout(reader, this.globalCodeScope);

                // Check if there is a post process function for this block.
                if (this.postProcessingFunctions.Keys.Contains(layoutCreators[i].TagBlockDefinition.s_tag_block_definition.Name) == true)
                {
                    // Invoke the post processing function.
                    this.postProcessingFunctions[layoutCreators[i].TagBlockDefinition.s_tag_block_definition.Name].Invoke(null,
                                                                                                                          new object[] { layoutCreators[i] });
                }

                // Write it to file.
                layoutCreators[i].WriteToFile(outputFolder);
            }
        }