public SndData(Blam.Halo3.Tags.cache_file_sound_group def) { Flags = (ushort)def.Flags.Value; SoundClass = (byte)def.SoundClass.Value; SampleRate = (byte)def.SampleRate.Value; Encoding = (byte)def.Encoding.Value; CodecIndex = (byte)def.CodecIndex.Value; PlaybackIndex = def.PlaybackIndex.Value; Unk08 = def.Unknown08.Value; Unk0A = def.Unknown0A.Value; // int h1, h2, h3; // h1 = Flags; // h1 <<= 8; // h1 |= SoundClass; // h1 <<= 8; // h1 |= SampleRate; // // h2 = Encoding; // h2 <<= 8; // h2 |= CodecIndex; // h2 <<= 8; // h2 |= (ushort)PlaybackIndex; // // h3 = Unk08; // h3 <<= 16; // h3 |= (ushort)Unk0A; // // kHashCode = h1 ^ h2 ^ h3; kHashCode = CodecIndex; }
/// <summary> /// Convert a halo 1 render model to the halo 2 version /// </summary> /// <param name="halo1"></param> /// <param name="halo2"></param> /// <returns></returns> public bool Definitions( Blam.Halo1.Tags.gbxmodel_group halo1, Tags.render_model_group halo2 ) { return true; }
/// <summary> /// Convert a halo 1 collision model to the halo 2 version /// </summary> /// <param name="halo1"></param> /// <param name="halo2"></param> /// <returns></returns> public bool Definitions( Blam.Halo1.Tags.model_collision_group halo1, Tags.collision_model_group halo2 ) { return true; }
/// <summary> /// Indexer into this tag index /// </summary> /// <param name="tag_index">datum index of a tag</param> /// <returns>Tag manager for the referenced tag</returns> /// <see cref="DataArray{T}"/> public override TagManager this[Blam.DatumIndex tag_index] { get { SentinelException(tag_index, "get"); return Array[tag_index]; } }
/// <summary> /// Convert a halo 1 sound tag to the halo 2 version /// </summary> /// <param name="halo1"></param> /// <param name="halo2"></param> /// <returns></returns> public bool Definitions( Blam.Halo1.Tags.sound_group halo1, Tags.sound_group halo2 ) { return true; }
public static void InteropReadNodes(Blam.CacheFile cf, int cache_offset, TagInterface.IBlock hs_nodes) { cf.InputStream.Seek(cache_offset, System.IO.SeekOrigin.Begin); hs_nodes.ReadHeader(cf); hs_nodes.Read(cf); }
public static void Output(Blam.Halo3.CacheFileBase c, System.IO.StreamWriter s, cache_file_resource_gestalt_group def) { resource_type_block.Output(s, def.ResourceTypes); s.WriteLine(); resource_structure_type_block.Output(s, def.ResourceStructureTypes); s.WriteLine(); cache_file_resource_gestalt_tag_resource_block.Output(s, def.TagResources); s.WriteLine(); cache_file_resource_gestalt_64_block.Output(s, def.Block64, "64-general"); cache_file_resource_gestalt_64_block.Output(s, def.Block70, "70-global"); cache_file_resource_gestalt_64_block.Output(s, def.Block7C, "7C-attached?"); cache_file_resource_gestalt_64_block.Output(s, def.Block88, "88-unattached"); cache_file_resource_gestalt_64_block.Output(s, def.Block94, "94-dvd_forbidden"); cache_file_resource_gestalt_64_block.Output(s, def.BlockA0, "A0-dvd_always_streaming"); cache_file_resource_gestalt_64_block.Output(s, def.BlockAC, "AC-bsp zones-1"); cache_file_resource_gestalt_64_block.Output(s, def.BlockB8, "B8-bsp zones-2"); cache_file_resource_gestalt_64_block.Output(s, def.BlockC4, "C4-bsp zones-3"); cache_file_resource_gestalt_64_block.Output(s, def.BlockD0, "D0-?"); cache_file_resource_gestalt_64_block.Output(s, def.BlockDC, "DC-zone sets"); cache_file_resource_gestalt_100_block.Output(s, def.Block100); cache_file_resource_gestalt_164_block.Output(s, def.Block164); Output(s, def.Block1D0); s.WriteLine(); cache_file_resource_gestalt_1DC_block.Output(s, def.Block1DC); s.WriteLine(); cache_file_resource_gestalt_1E8_block.Output(s, def.Block1E8); s.WriteLine(); cache_file_resource_gestalt_1F4_block.Output(s, def.Block1F4); s.WriteLine(); cache_file_resource_gestalt_200_block.Output(c, s, def.Block200); s.WriteLine(); }
public void InvalidVolume_ThrowsException_True() { var configuration = new Blam(); var ex = Assert.Throws <ArgumentOutOfRangeException>(() => configuration.Audio.Volume.Music = 15); StringAssert.Contains("Assigned volume value is greater than 10.", ex.Message); }
public void InvalidSensitivity_ThrowsException_True() { var configuration = new Blam(); var ex = Assert.Throws <ArgumentOutOfRangeException>(() => configuration.Mouse.Sensitivity.Horizontal = 11); StringAssert.Contains("Assigned sensitivity value is less than 1 or greater than 10.", ex.Message); }
public void InvalidResolution_ThrowsException_True() { var configuration = new Blam(); var ex = Assert.Throws <ArgumentOutOfRangeException>(() => configuration.Video.Resolution.Width = 0); StringAssert.Contains("Assigned dimension value is either 0 or over 32767.", ex.Message); }
public void InvalidName_ThrowsException_True() { var configuration = new Blam(); var ex = Assert.Throws <ArgumentOutOfRangeException>(() => configuration.Name = "Hello from Gensokyo"); StringAssert.Contains("Assigned name value is greater than 11 characters.", ex.Message); }
public ScenarioScriptInterop(Blam.HaloOdst.CacheFile cf) : base(cf, new TagInterface.Block<Blam.Halo3.Tags.hs_scripts_block>(null, 0), 0x3E0 + 0x4C, 0x3F4 + 0x4C, 0x400 + 0x4C, 0x4A4 + 0x4C) { hs_scripts = base.sncr_hs_scripts as TagInterface.Block<Blam.Halo3.Tags.hs_scripts_block>; }
/// <summary> /// Determines if the tag_index is marked up with any special sentinel values /// </summary> /// <param name="di">The tag_index handle</param> /// <returns>True if tag index is marked up</returns> public static bool IsSentinel(Blam.DatumIndex di) { if ( di == kMissing || di == kSkipped || di == kVersionInvalid ) return true; return false; }
public Scripting.ScriptNode Get(Blam.DatumIndex index, bool throw_exception) { if (index < 0 || index > Nodes.Count) if (throw_exception) throw new Debug.ExceptionLog("Index is not valid. {0:X} {1:X}", index); else return null; return Nodes[index]; }
/// <summary>Initialize the extraction process</summary> /// <param name="tag_datum"></param> /// <param name="args"></param> /// <returns></returns> public Blam.CacheExtractionInfo ExtractionBegin(Blam.DatumIndex tag_datum, Blam.CacheExtractionArguments args) { if (tag_datum == Blam.DatumIndex.Null) throw new ArgumentNullException("tag_datum", "Null datum index!"); var cei = new Blam.CacheExtractionInfo(cacheFile, tag_datum, args); cacheFile.PrepareForExtraction(cei); return cei; }
internal override bool Reconstruct(Blam.CacheFile c) { var rsrc_cache = Program.Halo2.FromLocation(c as Halo2.CacheFile, GetOffset()); // the shared cache isn't loaded, break if (rsrc_cache == null) return false; rsrc_cache.InputStream.Seek(GetOffset().Offset); Data = rsrc_cache.InputStream.ReadBytes(GetSize()); return true; }
protected override void ReadTagInstances(IO.EndianReader s, Blam.CacheFile cache) { // Read the tag index items items = new CacheItem[tagCount]; for (int x = 0; x < tagCount; x++) (items[x] = new CacheItem()).Read(s); // Read the tag filename strings foreach (Stubbs.CacheItem ci in items) ci.ReferenceName = cache.References.AddOptimized(ci.GroupTag, s.ReadCString()); }
/// <summary> /// For deciding if <paramref name="tag_datum"/> exists on disk already and thus shouldn't be extracted /// </summary> /// <param name="cei"></param> /// <param name="tag_datum">Engine's index of the tag instance</param> /// <returns>True if the tag exists on disk, false if it doesn't</returns> protected virtual bool ExtractionTagExistsOnDisk(Blam.CacheExtractionInfo cei, Blam.DatumIndex tag_datum) { if(!cei.Arguments.OverwriteExisting) { string base_dir = cei.Arguments.OutputDirectory; string tag_name = cacheFile.GetTagIndexName(tag_datum, true); return File.Exists(Path.Combine(base_dir, tag_name)); } return false; }
public static void InteropReadTagData(Blam.CacheFile cf, TagInterface.IBlock hs_scripts, int cache_offset_scripts, TagInterface.IBlock hs_globals, int cache_offset_globals) { cf.InputStream.Position = cache_offset_scripts; hs_scripts.ReadHeader(cf); hs_scripts.Read(cf); cf.InputStream.Position = cache_offset_globals; hs_globals.ReadHeader(cf); hs_globals.Read(cf); }
static void ExtractImportInfo(Blam.Halo2.Tags.global_tag_import_info_block tii, string out_path) { if (tii != null) foreach (var b in tii.Files) { var path = Path.Combine(out_path, b.Path.Value); var dir = Path.GetDirectoryName(path); if (!Directory.Exists(dir)) Directory.CreateDirectory(dir); using (var fs = File.Create(path)) { byte[] data = b.Decompress(); fs.Write(data, 0, data.Length); } } }
/// <summary>For deciding if <paramref name="tag_datum"/> shouldn't be extracted to disc or not</summary> /// <param name="cei"></param> /// <param name="tag_datum">Engine's index of the tag instance</param> /// <returns>True if the tag is not suppose to be extract, false if it is</returns> protected virtual bool ExtractionDontExtract(Blam.CacheExtractionInfo cei, Blam.DatumIndex tag_datum) { bool dont_extract = false; var ignore_groups = cei.Arguments.DontExtractGroups; if (ignore_groups != null) { var item = cacheFile.Index.Tags[tag_datum.Index]; dont_extract = ignore_groups.Contains(item.GroupTag); } // tag isn't of a group tag which we're ignoring so then check if // it is ignored for already existing if(!dont_extract) dont_extract = ExtractionTagExistsOnDisk(cei, tag_datum); return dont_extract; }
public static void InteropReadStringData(Blam.CacheFile cf, int cache_offset, out Util.StringPool strings_pool, byte k_pad_character) { strings_pool = new Util.StringPool(); cf.InputStream.Seek(cache_offset, System.IO.SeekOrigin.Begin); var hs_strings = new BlamLib.TagInterface.Data(); hs_strings.ReadHeader(cf); if (hs_strings.Size == 0) return; hs_strings.Read(cf); int offset = 0; byte btchar = 0; while (true) { var stringEntry = new System.Text.StringBuilder(); try { do { if (offset < hs_strings.Size) { btchar = hs_strings[offset]; if (btchar != 0) stringEntry.Append((char)btchar); } offset++; } while ((btchar != 0 && btchar != k_pad_character) && offset < hs_strings.Size); } catch (IndexOutOfRangeException ex) { throw new BlamLib.Debug.ExceptionLog("Offset was outside the bounds of the data array. {0}{1}", BlamLib.Program.NewLine, ex); } strings_pool.Add(stringEntry.ToString()); if (btchar == k_pad_character) break; } }
protected static void SecurityAesDecrypt(BlamVersion game, Blam.CacheSectionType section_type, byte[] input, out byte[] output, GetAesParametersProc GetAesParameters) { output = null; using (var aesm = new Crypt.AesManaged()) { aesm.KeySize = 128; aesm.Padding = Crypt.PaddingMode.Zeros; aesm.Mode = Crypt.CipherMode.CBC; byte[] key, iv; GetAesParameters(game, section_type, out key, out iv); if (key != null && iv != null) using (var ctx = aesm.CreateDecryptor(key, iv)) { output = ctx.TransformFinalBlock(input, 0, input.Length); } } }
public void ToString(int index, Blam.Halo3.CacheFileBase cf, StreamWriter sw) { if (tag_index.Index == ushort.MaxValue) { sw.WriteLine("{0:X}\t(NULL)", index); return; } var ci = cf.IndexHalo3[tag_index.Index]; sw.WriteLine("{0:X}\t{1} {2}", index, ci.GroupTag.Name, cf.GetReferenceName(ci)); sw.WriteLine( "\ttype: {0}" + Program.NewLine + "\tstart: {1:X}" + Program.NewLine + "\tsize: {2:X}" + Program.NewLine + "\toffset: {3:X}" + Program.NewLine + "\tresources: {4:X}\t{5:X}" + Program.NewLine + "\tdefinitions: {6:X}\t{7:X}", resource_type, start_offset, total_size, offset, resources_count, resources_offset, definitions_count, definitions_offset ); }
public void Read(Blam.Halo3.CacheFileBase cf) { cf.InputStream.Seek(4 + 4 + 4, SeekOrigin.Current); tag_index.Read(cf.InputStream); cf.InputStream.ReadInt16(); resource_type = cf.InputStream.ReadByte(); cf.InputStream.ReadByte(); start_offset = cf.InputStream.ReadInt32(); total_size = cf.InputStream.ReadInt32(); offset = cf.InputStream.ReadInt32(); cf.InputStream.ReadInt16(); cf.InputStream.ReadInt16(); cf.InputStream.ReadInt32(); resources_count = cf.InputStream.ReadInt32(); resources_offset = cf.InputStream.ReadPointer(); cf.InputStream.ReadInt32(); definitions_count = cf.InputStream.ReadInt32(); definitions_offset = cf.InputStream.ReadPointer(); cf.InputStream.ReadInt32(); }
protected abstract void ReadTagInstances(IO.EndianReader s, Blam.CacheFile cache);
void InitializeBspTags(IO.EndianReader s, Blam.CacheFile cache) { // Seek to the scenario's scenario_structure_bsps_block tag_block field s.Seek(items[0].Offset + 1444, System.IO.SeekOrigin.Begin); bspTags = new Item[s.ReadInt32()]; uint sbsp_offset = s.ReadPointer(); // Seek to the scenario_structure_bsps_block definitions s.Seek(sbsp_offset, System.IO.SeekOrigin.Begin); DatumIndex di = new DatumIndex(); CacheItemBase item = null; // Process each definition's runtime data for (int x = 0; x < bspTags.Length; x++) { s.Seek(28, System.IO.SeekOrigin.Current); di.Read(s); item = items[di.Index]; bspTags[x] = item as CacheItemBase; // Seek back to the beginning of the definition so the following stream code works s.Seek(-Halo1.Tags.scenario_structure_bsps_block.kSizeOf, System.IO.SeekOrigin.Current); // We're actually selectively reading scenario_structure_bsps_block fields here // The offset actually points to the bsp header, and the bsp comes after that header item.Offset = s.ReadInt32() + Halo1.Tags.scenario_structure_bsps_header.kSizeOf; item.Size = s.ReadInt32(); cache.BspAddressMasks.Add(s.ReadUInt32() - (uint)item.Offset); // won't count the header item.BspIndex = bspCount++; // Seek to the end of this definition, and thus, the start of the next definition s.Seek(20, System.IO.SeekOrigin.Current); } }
internal bool Reconstruct(Blam.CacheFile c, lightmap_vertex_buffer_bucket_block buffer_bucket, geometry_block_info_struct gbi) { int index = 0; int x; byte[][] data = gbi.GeometryBlock; if (data == null) return false; foreach (geometry_block_resource_block gb in gbi.Resources) { using (IO.EndianReader er = new BlamLib.IO.EndianReader(data[index])) { switch (gb.Type.Value) { #region TagBlock case (int)geometry_block_resource_type.TagBlock: int count = gb.GetCount(); switch (gb.PrimaryLocater.Value) { case OffsetVertexBuffers: VertexBuffers.Resize(count); VertexBuffers.Read(er); break; } break; #endregion #region VertexBuffer case (int)geometry_block_resource_type.VertexBuffer: var vb_defs = (c.TagIndexManager as InternalCacheTagIndex).kVertexBuffers; var stream_readers = new Render.VertexBufferInterface.StreamReader[VertexBuffers.Count]; for (x = 0; x < VertexBuffers.Count; x++) VertexBuffers[x].VertexBuffer.InitializeStreamReader(vb_defs, out stream_readers[x]); int vertex_count = gb.Size.Value / VertexBuffers[0].VertexBuffer.StrideSize; if(buffer_bucket.RawVertices.Count == 0) buffer_bucket.RawVertices.Resize(vertex_count); for (x = 0; x < vertex_count; x++) buffer_bucket.RawVertices[x].Reconstruct(buffer_bucket, gb, er, stream_readers); break; #endregion } } index++; } VertexBuffers.DeleteAll(); return true; }
internal override bool Reconstruct(Blam.CacheFile c) { bool result = true; if (CacheData.Count != 1) { lightmap_vertex_buffer_bucket_cache_data_block cache_data; CacheData.Add(out cache_data); result = cache_data.Reconstruct(c, this, GeometryBlockInfo); } GeometryBlockInfo.Value.ClearPostReconstruction(); return result; }
internal bool Reconstruct(Blam.CacheFile c, global_geometry_section_info_struct section_info, geometry_block_info_struct gbi) { return Geometry.Value.Reconstruct(c, section_info, gbi); }
void ExtractWriteTagDatabase(Blam.CacheExtractionInfo cei, TagManager root_tag, TagInterface.TagGroup database_group, TagInterface.Definition db_definition, bool is_error_db) { if ((db_definition as ITagDatabase).IsEmpty) return; // name the database after the root tag we're extracting string tag_name = root_tag.Name; if (is_error_db) tag_name = string.Format("{0}.errors", tag_name); Blam.CacheIndex.Item tdb_item; // Just in-case someone tries to extract the same root tag twice if (!cacheFile.TryAndFind(tag_name, database_group, out tdb_item)) { tdb_item = cacheFile.AddFeignTagInstance(tag_name, database_group); if (tdb_item == null) { extractionTrace.WriteLine("Couldn't create a tag_database for {0}! Couldn't create tag entry for database", root_tag.Name); return; } } try { var tdb_index = this.Open(tdb_item.Datum); var tdb = this[tdb_index]; tdb.Manage(db_definition); // Even though the tag isn't actually in the cache, the tag // manager needs to operate this way with CacheTagIndex elements tdb.OpenForExtract(cei.Arguments.OutputDirectory, null); tdb.Extract(); tdb.Close(); Unload(tdb_index); } catch(Exception ex) { extractionTrace.WriteLine("Error while trying to write tag_database!"); extractionTrace.WriteLine(ex); } }
/// <summary> /// /// </summary> /// <param name="cei"></param> /// <returns>True if any tags were extracted and if they extracted successfully. False if otherwise</returns> public bool Extract(Blam.CacheExtractionInfo cei) { if (!ExtractionDontExtract(cei, cei.Definition.Datum)) return Extract(cei, cei.Definition.Datum, false); return false; }
/// <summary>Extract an existing tag to a file</summary> /// <param name="tag_datum">index of tag to extract</param> /// <param name="base_directory">Root directory to extract the tag to</param> /// <returns>false if it can't save the tag</returns> public bool Extract(Blam.DatumIndex tag_datum, string base_directory) { return Extract(tag_datum, base_directory, null); }
/// <summary>Extract an existing tag to a file</summary> /// <param name="tag_datum">index of tag to extract</param> /// <param name="base_directory">Root directory to extract the tag to</param> /// <param name="name_override">Optional, if not null, this is the name of the file we store the tag in</param> /// <returns>false if it can't save the tag</returns> public bool Extract(Blam.DatumIndex tag_datum, string base_directory, string name_override) { Blam.DatumIndex handle = Open(tag_datum); if (handle != Blam.DatumIndex.Null) { TagManager tm = Array[handle]; try { tm.OpenForExtract(base_directory, name_override); tm.Extract(); } catch (Exception ex) { extractionTrace.WriteLine("Couldn't extract tag: '{0}'{1}{2}", tm.Name, Program.NewLine, ex); return false; } } else return false; return true; }