/// <summary> /// Reads the field set using the supplied guerilla binary reader. /// </summary> /// <param name="reader">The reader.</param> internal void Read(H2Guerilla.GuerillaBinaryReader reader) { var fieldSet = reader.ReadTagFieldSet(); version = new FieldSetVersion(fieldSet.Version); size = fieldSet.Size; alignmentBit = fieldSet.AlignmentBit; parentVersionIndex = fieldSet.ParentVersionIndex; fieldsAddress = fieldSet.FieldsAddress; address = fieldSet.Address; sizeString = reader.ReadLocalizedString(fieldSet.SizeStringAddress); }
/// <summary> /// Processes the supplied guerilla executable and language library retrieving all tag group and tag block definitions. /// </summary> /// <param name="guerillaFileName">The path of the H2Guerilla executable.</param> /// <param name="languageFileName">The path of the H2alang dynamic link library.</param> public void Process(string guerillaFileName, string languageFileName) { //Clear tagBlocks.Clear(); blockNameLookup.Clear(); blockAddressLookup.Clear(); tagGroups.Clear(); //Write Console.WriteLine("Processing Guerilla..."); Console.WriteLine("Guerilla path: {0}", guerillaFileName); Console.WriteLine("Library path: {0}", languageFileName); //Initialize stream using (FileStream fs = new FileStream(guerillaFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) using (H2Guerilla.GuerillaBinaryReader reader = new H2Guerilla.GuerillaBinaryReader(languageFileName, fs)) { //Prepare for (int i = 0; i < Guerilla.NumberOfTagLayouts; i++) { //Goto fs.Seek(Guerilla.TagLayoutTableAddress - Guerilla.BaseAddress + (i * 4), SeekOrigin.Begin); int layoutAddress = reader.ReadInt32(); //Read layout address //Goto fs.Seek(layoutAddress - Guerilla.BaseAddress, SeekOrigin.Begin); tagGroups.Add(new TagGroupDefinition(reader)); //Read Tag group //Read Console.WriteLine("Reading tag_group {0}...", tagGroups[i].GroupTag); Console.WriteLine("Processing..."); //Add if (!groupAddressLookup.ContainsKey(tagGroups[i].DefinitionAddress)) { groupAddressLookup.Add(tagGroups[i].DefinitionAddress, i); } if (!groupTagLookup.ContainsKey(tagGroups[i].GroupTag)) { groupTagLookup.Add(tagGroups[i].GroupTag, i); } //Read tag block definition ReadTagBlockDefinition(fs, reader, tagGroups[i].DefinitionAddress, null); //Set tagBlocks[blockAddressLookup[tagGroups[i].DefinitionAddress]].IsTagGroup = true; } } }
/// <summary> /// Initializes a new instance of the <see cref="TagBlockDefinition"/> using the supplied guerilla reader. /// </summary> /// <param name="reader">The guerilla binary reader.</param> internal TagBlockDefinition(H2Guerilla.GuerillaBinaryReader reader) : this() { //Read tag block definition H2Guerilla.TagBlockDefinition tagBlockDefinition = reader.ReadTagBlockDefinition(); //Initialize flags = tagBlockDefinition.Flags; maximumElementCount = tagBlockDefinition.MaximumElementCount; fieldSetsAddress = tagBlockDefinition.FieldSetsAddress; fieldSetCount = tagBlockDefinition.FieldSetCount; fieldSetLatestAddress = tagBlockDefinition.FieldSetLatestAddress; displayName = reader.ReadLocalizedString(tagBlockDefinition.DisplayNameAddress); name = reader.ReadLocalizedString(tagBlockDefinition.NameAddress); maximumElementCountString = reader.ReadLocalizedString(tagBlockDefinition.MaximumElementCountStringAddress); }
/// <summary> /// Initializes a new instance of the <see cref="TagGroupDefinition"/> class using the supplied guerilla reader. /// </summary> /// <param name="reader">The guerilla binary reader.</param> internal TagGroupDefinition(H2Guerilla.GuerillaBinaryReader reader) : this() { //Read tag group H2Guerilla.TagGroup tagGroup = reader.ReadTagGroup(); //Setup flags = tagGroup.Flags; groupTag = tagGroup.GroupTag; parentGroupTag = tagGroup.ParentGroupTag; version = tagGroup.Version; initialized = tagGroup.Initialized; definitionAddress = tagGroup.DefinitionAddress; childGroupTags = tagGroup.ChildGroupTags; childsCount = tagGroup.ChildsCount; defaultTagPath = reader.ReadLocalizedString(tagGroup.DefaultTagPathAddress); name = reader.ReadLocalizedString(tagGroup.NameAddress); }
/// <summary> /// Reads a tag block using the supplied stream, guerilla reader, definition address, sound override boolean, and parent tag block definition. /// </summary> /// <param name="input">The guerilla stream.</param> /// <param name="reader">The guerilla reader.</param> /// <param name="address">The address of the tag block definition.</param> /// <param name="parent">The parent tag block.</param> private void ReadTagBlockDefinition(Stream input, H2Guerilla.GuerillaBinaryReader reader, int address, TagBlockDefinition parent) { //Check if (blockAddressLookup.ContainsKey(address)) { return; } //Goto input.Seek(address - Guerilla.BaseAddress, SeekOrigin.Begin); TagBlockDefinition definition = new TagBlockDefinition(reader) { Address = address, }; //Initialize tag field sets definition.tagFieldSets = new TagFieldSetDefinition[definition.FieldSetCount]; //Processing Console.WriteLine("Processing tag_block {0}", definition.Name); //Check if (definition.Name == "hud_waypoint_arrow_block" && definition.Address == 9689580) { definition.Name = "hud_globals_waypoint_arrow_block"; } //Check if (definition.Name == "sound_block") { //Override sound block definition.FieldSetCount = 1; definition.FieldSetsAddress = 0x957870; definition.FieldSetLatestAddress = 0x906178; definition.tagFieldSets = new TagFieldSetDefinition[1]; definition.TagFieldSetLatestIndex = 0; definition.tagFieldSets[0] = new TagFieldSetDefinition { Version = new TagFieldSetDefinition.FieldSetVersion { FieldsAddress = 0x906178, Index = 0, SizeOf = -1, UpgradeProcedure = 0 }, Size = 172, AlignmentBit = 0, ParentVersionIndex = -1, FieldsAddress = 0x906178, SizeString = "sizeof(sound_definition)", }; } else { //Read field set definitions for (int i = 0; i < definition.FieldSetCount; i++) { //Goto input.Seek(definition.FieldSetsAddress + (i * 76) - Guerilla.BaseAddress, SeekOrigin.Begin); definition.tagFieldSets[i] = new TagFieldSetDefinition(); definition.tagFieldSets[i].Read(reader); //Check if (definition.FieldSetLatestAddress == definition.tagFieldSets[i].Address) { definition.TagFieldSetLatestIndex = i; } } } //Read fields for each field set for (int i = 0; i < definition.FieldSetCount; i++) { //Goto input.Seek(definition.tagFieldSets[i].FieldsAddress - Guerilla.BaseAddress, SeekOrigin.Begin); //Read fields for field set TagFieldDefinition field = null; int index = 0; do { //Store address long fieldAddress = input.Position; //Read the field type switch ((FieldType)reader.ReadInt16()) { case FieldType.FieldSkip: field = new TagFieldDefinition(); break; case FieldType.FieldTagReference: field = new TagFieldTagReferenceDefinition(); break; case FieldType.FieldStruct: field = new TagFieldStructDefinition(); break; case FieldType.FieldData: field = new TagFieldDataDefinition(); break; case FieldType.FieldByteFlags: case FieldType.FieldLongFlags: case FieldType.FieldWordFlags: case FieldType.FieldCharEnum: case FieldType.FieldEnum: case FieldType.FieldLongEnum: field = new TagFieldEnumDefinition(); break; case FieldType.FieldCharBlockIndex2: case FieldType.FieldShortBlockIndex2: case FieldType.FieldLongBlockIndex2: field = new TagFieldBlockIndexCustomSearchDefinition(); break; case FieldType.FieldExplanation: field = new TagFieldExplanationDefinition(); break; case FieldType.FieldArrayStart: field = new TagFieldArrayStartDefinition(); break; default: field = new TagFieldDefinition(); break; } //Goto field input.Seek(fieldAddress, SeekOrigin.Begin); field.Read(reader); //Add definition.FieldSets[i].Fields.Add(field); //Handle special field type switch (field.Type) { case FieldType.FieldByteBlockFlags: case FieldType.FieldWordBlockFlags: case FieldType.FieldLongBlockFlags: case FieldType.FieldCharInteger: case FieldType.FieldShortInteger: case FieldType.FieldLongInteger: case FieldType.FieldBlock: if (field.DefinitionAddress != 0) { ReadTagBlockDefinition(input, reader, field.DefinitionAddress, definition); } break; case FieldType.FieldStruct: if (field is TagFieldStructDefinition structField) { ReadTagBlockDefinition(input, reader, structField.BlockDefinitionAddresss, definition); } break; } //Goto next field input.Seek(fieldAddress + field.Nudge, SeekOrigin.Begin); //Increment index++; }while (field.Type != FieldType.FieldTerminator); } //Check switch (definition.Name) { case "materials_block": definition.TagFieldSetLatestIndex = 0; if (definition.FieldSets[definition.TagFieldSetLatestIndex].Fields.Count == 5) { definition.Name = "physics_model_materials_block"; definition.DisplayName = "physics_model_materials_block"; } break; case "hud_globals_block": case "global_new_hud_globals_struct_block": case "sound_gestalt_promotions_block": case "sound_block": case "tag_block_index_struct_block": case "vertex_shader_classification_block": definition.TagFieldSetLatestIndex = 0; break; case "instantaneous_response_damage_effect_marker_struct_block": case "instantaneous_response_damage_effect_struct_block": definition.TagFieldSetLatestIndex = 1; break; case "animation_pool_block": definition.TagFieldSetLatestIndex = 4; break; } //Add if (!blockNameLookup.ContainsKey(definition.Name)) { blockNameLookup.Add(definition.Name, tagBlocks.Count); } blockAddressLookup.Add(address, tagBlocks.Count); tagBlocks.Add(definition); }