示例#1
0
        /// <summary>
        /// Creates a new enum or bitmask type definition in the current code object.
        /// </summary>
        /// <param name="codeScope">Code scope of the enum for ensuring each flag option is unique.</param>
        /// <param name="field">Enum definition from Guerilla.</param>
        public void AddEnumOrBitmask(MutationCodeScope codeScope, enum_definition field)
        {
            // Determine the underlying type for the enum based on the field type.
            Type fieldType = ValueTypeDictionary[field.type];

            // Create the enum field by creating a new CodeTypeDeclaration.
            CodeTypeDeclaration @enum = new CodeTypeDeclaration(codeScope.Namespace);

            @enum.IsEnum = true;
            @enum.BaseTypes.Add(fieldType);

            // Check if this field is a bitmask and if so add the Flags attribute.
            if (codeScope.Type == MutationCodeScopeType.Bitmask)
            {
                // Setup a code attribute declaration object for the Flags attribute.
                CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(new CodeTypeReference(typeof(FlagsAttribute).Name));
                @enum.CustomAttributes.Add(attribute);
            }

            // Loop through all of the enum options and add each one to the enum field.
            for (int i = 0; i < field.option_count; i++)
            {
                // Check if the option name is valid and if not skip it.
                if (field.options[i] == string.Empty)
                {
                    continue;
                }

                // Create a code safe field name for the enum option.
                string            displayName, units, tooltip;
                EditorMarkUpFlags markupFlags;
                string            optionName = codeScope.CreateCodeSafeFieldName(field_type._field_enum_option, field.options[i], out displayName, out units, out tooltip, out markupFlags);

                // Create a new CodeMemberField for the enum option.
                CodeMemberField option = new CodeMemberField
                {
                    Name = optionName,

                    // Set the flag value accordingly.
                    InitExpression = new CodeSnippetExpression(string.Format("0x{0}",
                                                                             (codeScope.Type == MutationCodeScopeType.Bitmask ? (1 << i) : i).ToString("x"))),
                };

                // Create a new UI markup attribute and add it to the enum option.
                option.CustomAttributes.Add(EditorMarkUpAttribute.CreateAttributeDeclaration(flags: markupFlags, displayName: displayName, unitsSpecifier: units, tooltipText: tooltip));

                // Add the option to the enum.
                @enum.Members.Add(option);
            }

            // Add the enum to the class definition.
            this.CodeClass.Members.Add(@enum);
        }
示例#2
0
        private void ReadTagBlockDefinition(int address, bool isSound, TagBlockDefinition parent)
        {
            // Check if this tag_block_definition has already been read.
            if (this.TagBlockDefinitions.ContainsKey(address) == true)
            {
                //// Check if this definition has a parent and if so add a reference to it.
                //if (parent != null)
                //{
                //    // Add the parent defintion as a reference.
                //    this.TagBlockDefinitions[address].AddReference(parent);
                //}

                // Don't process the tag block.
                return;
            }

            // Seek to the definition address.
            this.reader.BaseStream.Position = address - Guerilla.BaseAddress;

            // Initialize and read the tag_block_definition struct.
            TagBlockDefinition tagBlockDef = new TagBlockDefinition();

            tagBlockDef.s_tag_block_definition.address = address;
            tagBlockDef.s_tag_block_definition.Read(h2LangLib, reader);

            // Special case tags may need the field set addresses adjusted.
            if (isSound == true)
            {
                tagBlockDef.s_tag_block_definition.field_sets_address       = 0;// 0x906178;
                tagBlockDef.s_tag_block_definition.field_set_count          = 6;
                tagBlockDef.s_tag_block_definition.field_set_latest_address = 0x906178;
            }

            // Initialize the tag field set arrays.
            tagBlockDef.TagFieldSets = new tag_field_set[tagBlockDef.s_tag_block_definition.field_set_count];
            tagBlockDef.TagFields    = new List <tag_field> [tagBlockDef.s_tag_block_definition.field_set_count];

            //// Check if this definition has a parent and if so add a reference to it.
            //if (parent != null)
            //{
            //    // Add the parent defintion as a reference.
            //    tagBlockDef.AddReference(parent);
            //}

            // Add the tag block definition to the dictionary.
            this.TagBlockDefinitions.Add(address, tagBlockDef);

            // Loop through all the tag_field_set's and read each one.
            for (int i = 0; i < tagBlockDef.s_tag_block_definition.field_set_count; i++)
            {
                // Special case tags may need the field set addresses adjusted.
                if (isSound == true)
                {
                    // Initialize the field set.
                    tagBlockDef.TagFieldSets[i] = new tag_field_set();

                    // Manuall fill in the information.
                    if (i == 0)
                    {
                        // Seek to the tag_field_set definition address.
                        reader.BaseStream.Position = 0x957A60 - Guerilla.BaseAddress;
                        tagBlockDef.TagFieldSets[i].Read(h2LangLib, reader);
                    }
                    else if (i == 1 || i == 2 || i == 3) // 2 & 3
                    {
                        // Seek to the tag_field_set definition address.
                        reader.BaseStream.Position = 0x957448 - Guerilla.BaseAddress;
                        tagBlockDef.TagFieldSets[i].Read(h2LangLib, reader);
                    }
                    else if (i == 4) // 4
                    {
                        tagBlockDef.TagFieldSets[i].version.fields_address = 0x906078;
                        tagBlockDef.TagFieldSets[i].version.index          = 0;
                        tagBlockDef.TagFieldSets[i].version.upgrade_proc   = 0x49F700;
                        tagBlockDef.TagFieldSets[i].version.size_of        = -1;
                        tagBlockDef.TagFieldSets[i].size                 = 176;
                        tagBlockDef.TagFieldSets[i].alignment_bit        = 0;
                        tagBlockDef.TagFieldSets[i].parent_version_index = -1;
                        tagBlockDef.TagFieldSets[i].fields_address       = 0x906078;
                        tagBlockDef.TagFieldSets[i].size_string          = "sizeof(struct sound_definition_v1)";
                    }
                    else if (i == 5) // 5
                    {
                        tagBlockDef.TagFieldSets[i].version.fields_address = 0x906178;
                        tagBlockDef.TagFieldSets[i].version.index          = 0;
                        tagBlockDef.TagFieldSets[i].version.upgrade_proc   = 0;
                        tagBlockDef.TagFieldSets[i].version.size_of        = -1;
                        tagBlockDef.TagFieldSets[i].size                 = 172;
                        tagBlockDef.TagFieldSets[i].alignment_bit        = 0;
                        tagBlockDef.TagFieldSets[i].parent_version_index = -1;
                        tagBlockDef.TagFieldSets[i].fields_address       = 0x906178;
                        tagBlockDef.TagFieldSets[i].size_string          = "sizeof(sound_definition)";
                    }
                }
                else
                {
                    // Seek to the tag_field_set definition address.
                    reader.BaseStream.Position = tagBlockDef.s_tag_block_definition.field_sets_address + (i * 76) - Guerilla.BaseAddress;

                    // Initialize and read the tag_field_set struct.
                    tagBlockDef.TagFieldSets[i] = new tag_field_set();
                    tagBlockDef.TagFieldSets[i].Read(h2LangLib, reader);
                }

                // Check if this is the latest tag field set.
                if (tagBlockDef.s_tag_block_definition.field_set_latest_address == tagBlockDef.TagFieldSets[i].address)
                {
                    tagBlockDef.TagFieldSetLatestIndex = i;
                }

                // Initialize the tag field list.
                tagBlockDef.TagFields[i] = new List <tag_field>();

                // Seek to the tag field set address.
                this.reader.BaseStream.Position = tagBlockDef.TagFieldSets[i].fields_address - Guerilla.BaseAddress;

                // Loop through all the tag fields and read each one.
                tag_field field = new tag_field();
                do
                {
                    // Save the current address.
                    long currentAddress = this.reader.BaseStream.Position;

                    // Read the field type from the stream.
                    field_type fieldType = (field_type)this.reader.ReadInt16();

                    // Create the field type accordingly.
                    switch (fieldType)
                    {
                    case field_type._field_tag_reference: field = new tag_reference_definition(); break;

                    case field_type._field_struct: field = new tag_struct_definition(); break;

                    case field_type._field_data: field = new tag_data_definition(); break;

                    case field_type._field_byte_flags:
                    case field_type._field_long_flags:
                    case field_type._field_word_flags:
                    case field_type._field_char_enum:
                    case field_type._field_enum:
                    case field_type._field_long_enum: field = new enum_definition(); break;

                    case field_type._field_char_block_index2:
                    case field_type._field_short_block_index2:
                    case field_type._field_long_block_index2: field = new block_index_custom_search_definition(); break;

                    case field_type._field_explanation: field = new explaination_definition(); break;

                    default: field = new tag_field(); break;
                    }

                    // Read the tag field from the stream.
                    this.reader.BaseStream.Position = currentAddress;
                    field.Read(h2LangLib, reader);

                    // Add the field to the list.
                    tagBlockDef.TagFields[i].Add(field);

                    // Read any tag_block definitions.
                    switch (field.type)
                    {
                    case field_type._field_byte_block_flags:
                    case field_type._field_word_block_flags:
                    case field_type._field_long_block_flags:
                    case field_type._field_char_integer:
                    case field_type._field_short_integer:
                    case field_type._field_long_integer:
                    case field_type._field_block:
                    {
                        // Check if the definition address is valid.
                        if (field.definition_address != 0)
                        {
                            ReadTagBlockDefinition(field.definition_address, false, tagBlockDef);
                        }
                        break;
                    }

                    case field_type._field_struct:
                    {
                        ReadTagBlockDefinition(((tag_struct_definition)field).block_definition_address, false, tagBlockDef);
                        break;
                    }
                    }

                    // Seek to the next tag_field.
                    this.reader.BaseStream.Position = currentAddress + 16; //sizeof(tag_field)
                }while (field.type != field_type._field_terminator);
            }
        }
示例#3
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;
                }
                }
            }
        }