bool ShaderExists(DatumIndex shader_datum) { foreach (var shader in shaders) if (shader.Datum == shader_datum) return true; return false; }
/// <summary>Add a tag to the extraction queue</summary> /// <param name="index"></param> public void Queue(DatumIndex index) { if (index == DatumIndex.Null) throw new ArgumentNullException("Can't queue a null tag index!"); if (Datums.ContainsKey(index)) return; Datums.Add(index, false); }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, BuildInformation buildInfo) { ResourceIndex = new DatumIndex(values.GetInteger("resource datum index")); LoadRegions(values, reader, metaArea, buildInfo); LoadSections(values, reader, metaArea, buildInfo); LoadBoundingBox(values, reader, metaArea, buildInfo); }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { ModelResourceIndex = new DatumIndex(values.GetInteger("model resource datum index")); LoadSections(values, reader, metaArea, buildInfo); LoadBoundingBoxes(values, reader, metaArea, buildInfo); }
public ThirdGenGlobal(StructureValueCollection values, ExpressionTable allExpressions) { Name = values.GetString("name"); Type = (short)values.GetInteger("type"); DatumIndex valueIndex = new DatumIndex(values.GetInteger("expression index")); if (valueIndex.IsValid) Value = allExpressions.FindExpression(valueIndex); }
/// <summary> /// Get a <see cref="TagGroup"/> via a handle stored in a <see cref="DatumIndex"/> object which is a strong reference /// and can be trusted to work even when streamed to a file and loaded at another time after the application /// has reset /// </summary> /// <param name="group_handle">Strong reference to a <see cref="TagGroup"/></param> /// <returns></returns> public static TagGroup TagGroupFromHandle(DatumIndex group_handle) { if (group_handle == DatumIndex.Null) return TagGroup.Null; BlamVersion engine = (BlamVersion)group_handle.Salt; ushort index = group_handle.Index; bool is_struct = Util.Flags.Test(index, (ushort)0x8000); switch(engine) { case BlamVersion.Halo1: return Halo1.TagGroups.Groups[index]; #if !NO_HALO2 case BlamVersion.Halo2: if (is_struct) return Halo2.StructGroups.Groups[index]; return Halo2.TagGroups.Groups[index]; #endif #if !NO_HALO3 case BlamVersion.Halo3: if (is_struct) return Halo3.StructGroups.Groups[index]; return Halo3.TagGroups.Groups[index]; #endif #if !NO_HALO_ODST case BlamVersion.HaloOdst: // TODO: ummm, add the code for struct groups //if (is_struct) return HaloOdst.StructGroups.Groups[index]; return HaloOdst.TagGroups.Groups[index]; #endif #if !NO_HALO_REACH case BlamVersion.HaloReach: if (is_struct) return HaloReach.StructGroups.Groups[index]; return HaloReach.TagGroups.Groups[index]; #endif #if !NO_HALO4 case BlamVersion.Halo4: if (is_struct) return Halo4.StructGroups.Groups[index]; return Halo4.TagGroups.Groups[index]; #endif case BlamVersion.Stubbs: return Stubbs.TagGroups.Groups[index]; case BlamVersion.Unknown: return MiscGroups.Groups[index]; default: throw new Debug.Exceptions.UnreachableException(engine); } }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, StringIDSource stringIDs, BuildInformation buildInfo) { Name = values.HasInteger("name index") ? stringIDs.GetString(new StringID(values.GetInteger("name index"))) : values.GetString("name"); ExecutionType = (short)values.GetInteger("execution type"); ReturnType = (short)values.GetInteger("return type"); RootExpressionIndex = new DatumIndex(values.GetInteger("first expression index")); if (Name == null) Name = "script_" + RootExpressionIndex.Value.ToString("X8"); Parameters = LoadParameters(reader, values, metaArea, buildInfo); }
public void AddShaderDatum(DatumIndex shader_datum, string name) { if (ShaderExists(shader_datum)) return; ShaderReference shader = new ShaderReference(); shader.Name = name; shader.Datum = shader_datum; shaders.Add(shader); }
private void Load(StructureValueCollection values, IReader reader, FileSegmentGroup metaArea, EngineDescription buildInfo) { SoundClass = (byte)values.GetInteger("sound class"); SampleRate = (SampleRate)values.GetInteger("sample rate"); Encoding = (Encoding)values.GetInteger("encoding"); CodecIndex = (byte)values.GetInteger("codec index"); PlaybackIndex = (short)values.GetInteger("playback index"); PermutationChunkCount = (byte)values.GetInteger("permutation chunk count"); ResourceIndex = new DatumIndex(values.GetInteger("resource datum index")); MaxPlaytime = (short)values.GetInteger("max playtime"); }
private void Load(StructureValueCollection values, ushort index, ThirdGenTagTable tags, ThirdGenResourceLayoutTable layoutInfo) { Index = new DatumIndex((ushort)values.GetInteger("datum index salt"), index); DatumIndex tagIndex = new DatumIndex(values.GetInteger("parent tag datum index")); if (tagIndex.IsValid) ParentTag = tags[tagIndex.Index]; int segmentIndex = (int)values.GetInteger("segment index"); if (segmentIndex >= 0 && segmentIndex < layoutInfo.Segments.Length) _segment = layoutInfo.Segments[segmentIndex]; }
private void Load(IReader reader, StructureValueCollection values, FileSegmentGroup metaArea, StringIDSource stringIDs, ExpressionTable expressions, BuildInformation buildInfo) { Name = stringIDs.GetString(new StringID((int)values.GetInteger("name index"))); ExecutionType = (short)values.GetInteger("execution type"); ReturnType = (short)values.GetInteger("return type"); DatumIndex rootExpr = new DatumIndex(values.GetInteger("first expression index")); if (rootExpr.IsValid) RootExpression = expressions.FindExpression(rootExpr); if (Name == null) Name = "script_" + rootExpr.Value.ToString("X8"); Parameters = LoadParameters(reader, values, metaArea, buildInfo); }
private void Load(StructureValueCollection values, ushort index, StringTableReader stringReader) { Index = new DatumIndex((ushort) values.GetInteger("datum index salt"), index); Opcode = (ushort) values.GetInteger("opcode"); ReturnType = (short) values.GetInteger("value type"); Type = (ScriptExpressionType) values.GetInteger("expression type"); _nextIndex = new DatumIndex(values.GetInteger("next expression index")); _stringTableOffset = (int) values.GetIntegerOrDefault("string table offset", 0); Value = values.GetInteger("value"); LineNumber = (short) values.GetIntegerOrDefault("source line", 0); stringReader.RequestString(_stringTableOffset); }
private void Load(StructureValueCollection values, FileSegmentGroup metaArea, Dictionary<int, ITagClass> classesById) { uint offset = values.GetInteger("offset"); if (offset > 0) MetaLocation = SegmentPointer.FromPointer(offset, metaArea); // Load the tag class by looking up the magic value that's stored var classMagic = (int) values.GetInteger("class magic"); if (classMagic != -1) Class = classesById[classMagic]; Index = new DatumIndex(values.GetInteger("datum index")); DataSize = (int) values.GetInteger("data size"); }
private void Load(StructureValueCollection values, ushort index, FileSegmentGroup metaArea, IList<ITagClass> classList) { uint address = values.GetInteger("memory address"); if (address != 0 && address != 0xFFFFFFFF) MetaLocation = SegmentPointer.FromPointer(address, metaArea); var classIndex = (int) values.GetInteger("class index"); if (classIndex >= 0 && classIndex < classList.Count) Class = classList[classIndex]; var salt = (ushort) values.GetInteger("datum index salt"); if (salt != 0xFFFF) Index = new DatumIndex(salt, index); else Index = DatumIndex.Null; }
internal CacheHeaderPcFields() { VirtualAddress = 0; TagDependencyGraphOffset = -1; TagDependencyGraphSize = 0; LanguagePacksOffset = -1; LanguagePacksSizeOf = 0; SecondarySoundGestalt = DatumIndex.Null; FastLoadGeometryBlockOffset = -1; FastLoadGeometryBlockSize = 0; MoppCodesChecksum = 0; }
public void Write(IO.EndianWriter stream) { Compiler comp = stream.Owner as Compiler; Import import = comp.OwnerState.Importer as Import; short real_count = (short)import.Groups.Count; var next_index = new DatumIndex((ushort)real_count, 0); // note that this default value isn't ideal stream.Write("dynamic tag groups", false); stream.Write(DataArray.MaxValue); stream.Write(Item.Size); stream.Write((byte)0); // alignment bit stream.Write(true); // is valid stream.Write((short)0); // flags MiscGroups.data.Write(stream); stream.Write(uint.MinValue); // allocator stream.Write((int)0); // bit vector next index stream.Write(Datums.Count); // bit vector length stream.Write(Datums.Count); // actual count next_index.Write(stream); // next index stream.WritePointer(stream.PositionUnsigned + 8); stream.Write((int)0); // bit vector pointer #region Write tag group datums foreach (Import.TagGroup tg in import.Groups.Values) { stream.Write((short)0); // Header stream.Write((short)0); // Flags comp.AddLocationFixup(tg.Name, stream, false); stream.Write((int)0); } #endregion #region Write null datums Item i = new Item(); int count = DataArray.MaxValue - real_count; for (int x = 0; x < count; x++) i.Write(stream); #endregion }
private bool GenerateScriptReference(ScriptExpression expression, IndentedTextWriter output) { var expressionIndex = new DatumIndex(expression.Value); _nextFunctionIsScript = true; GenerateCode(_scripts.Expressions.FindExpression(expressionIndex), output); _nextFunctionIsScript = false; return true; }
/// <summary> Unload the current structure bsp. </summary> void UnloadStructureBSP() { mTagHandler.IndexInterface.UnloadAll(); mTagHandler = null; mBSPDatumIndex = DatumIndex.Null; }
private static DataBlock ReadDataBlock(IReader reader, byte version) { if (version > 8) { throw new InvalidOperationException("Unrecognized \"data\" block version"); } // Block data uint originalAddress = reader.ReadUInt32(); int entryCount = (version >= 1) ? reader.ReadInt32() : 1; int align = (version >= 3) ? reader.ReadInt32() : 4; bool sort = false; if (version >= 7) { byte sortval = reader.ReadByte(); sort = sortval > 0; } byte[] data = ReadByteArray(reader); var block = new DataBlock(originalAddress, entryCount, align, sort, data); // Address fixups int numAddressFixups = reader.ReadInt32(); for (int i = 0; i < numAddressFixups; i++) { uint dataAddress = reader.ReadUInt32(); int writeOffset = reader.ReadInt32(); block.AddressFixups.Add(new DataBlockAddressFixup(dataAddress, writeOffset)); } // Tagref fixups int numTagFixups = reader.ReadInt32(); for (int i = 0; i < numTagFixups; i++) { var datum = new DatumIndex(reader.ReadUInt32()); int writeOffset = reader.ReadInt32(); block.TagFixups.Add(new DataBlockTagFixup(datum, writeOffset)); } // Resource reference fixups int numResourceFixups = reader.ReadInt32(); for (int i = 0; i < numResourceFixups; i++) { var datum = new DatumIndex(reader.ReadUInt32()); int writeOffset = reader.ReadInt32(); block.ResourceFixups.Add(new DataBlockResourceFixup(datum, writeOffset)); } if (version >= 2) { // StringID fixups int numSIDFixups = reader.ReadInt32(); for (int i = 0; i < numSIDFixups; i++) { string str = reader.ReadAscii(); int writeOffset = reader.ReadInt32(); block.StringIDFixups.Add(new DataBlockStringIDFixup(str, writeOffset)); } } if (version >= 4) { // Shader fixups int numShaderFixups = reader.ReadInt32(); for (int i = 0; i < numShaderFixups; i++) { int writeOffset = reader.ReadInt32(); int shaderDataSize = reader.ReadInt32(); byte[] shaderData = reader.ReadBlock(shaderDataSize); block.ShaderFixups.Add(new DataBlockShaderFixup(writeOffset, shaderData)); } } if (version >= 5) { // Unicode string list fixups int numUnicListFixups = reader.ReadInt32(); for (int i = 0; i < numUnicListFixups; i++) { // Version 5 is buggy and doesn't include a language index :x int languageIndex = i; if (version >= 6) { languageIndex = reader.ReadInt32(); } int writeOffset = reader.ReadInt32(); int numStrings = reader.ReadInt32(); UnicListFixupString[] strings = new UnicListFixupString[numStrings]; for (int j = 0; j < numStrings; j++) { string stringId = reader.ReadAscii(); string str = reader.ReadUTF8(); strings[j] = new UnicListFixupString(stringId, str); } block.UnicListFixups.Add(new DataBlockUnicListFixup(languageIndex, writeOffset, strings)); } } if (version >= 7) { int numInteropFixups = reader.ReadInt32(); for (int i = 0; i < numInteropFixups; i++) { uint dataAddress = reader.ReadUInt32(); int writeOffset = reader.ReadInt32(); int type = reader.ReadInt32(); block.InteropFixups.Add(new DataBlockInteropFixup(type, dataAddress, writeOffset)); } int numEffectFixups = reader.ReadInt32(); for (int i = 0; i < numEffectFixups; i++) { int index = reader.ReadInt32(); int writeOffset = reader.ReadInt32(); int type = reader.ReadInt32(); int effectDataSize = reader.ReadInt32(); byte[] effectData = reader.ReadBlock(effectDataSize); block.EffectFixups.Add(new DataBlockEffectFixup(type, index, writeOffset, effectData)); } } if (version >= 8) { int numSoundFixups = reader.ReadInt32(); for (int i = 0; i < numSoundFixups; i++) { int codec = reader.ReadInt32(); int prcount = reader.ReadInt32(); int pr = reader.ReadInt32(); int lpr = reader.ReadInt32(); int pb = reader.ReadInt32(); int sc = reader.ReadInt32(); int promo = reader.ReadInt32(); int cpb = reader.ReadInt32(); int ex = reader.ReadInt32(); block.SoundFixups.Add(new DataBlockSoundFixup(codec, prcount, pr, lpr, pb, sc, promo, cpb, ex)); } } return(block); }
protected XmlFile(byte[] buffer, string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) : base(fileName, datum, fileType, isBigEndian) { // Initialize fields. this.Buffer = buffer; }
/// <summary> /// Activates or deactivates a resource in the zone set. /// </summary> /// <param name="index">The datum index of the resource to activate or deactivate.</param> /// <param name="activate"><c>true</c> if the resource should be made active, <c>false</c> otherwise.</param> public void ActivateResource(DatumIndex index, bool activate) { _activeResources.Length = Math.Max(_activeResources.Length, index.Index + 1); _activeResources[index.Index] = activate; }
public override byte[] GetRawFromID(DatumIndex ID, int DataLength) { if (ID == DatumIndex.None) { return(null); } if (ResourceLayoutTable == null || ResourceGestalt == null) { LoadResourceTags(); } var resource = ResourceGestalt.TagResources[ID.Index]; if (resource.SegmentIndex == -1) { return(null); } var segment = ResourceLayoutTable.Segments[resource.SegmentIndex]; if (segment.RequiredPageIndex == -1 || segment.RequiredSegmentOffset == -1) { return(null); } int pageIndex = (segment.OptionalPageIndex != -1) ? segment.OptionalPageIndex : segment.RequiredPageIndex; int segmentOffset = (segment.OptionalSegmentOffset != -1) ? segment.OptionalSegmentOffset : segment.RequiredSegmentOffset; if (pageIndex == -1 || segmentOffset == -1) { return(null); } if (ResourceLayoutTable.RawPages[pageIndex].BlockOffset == -1) { pageIndex = segment.RequiredPageIndex; segmentOffset = segment.RequiredSegmentOffset; } var page = ResourceLayoutTable.RawPages[pageIndex]; var decompressed = ReadPageData(resource, page); var length = DataLength == -1 ? (page.UncompressedBlockSize - segmentOffset) : DataLength; var data = new byte[length]; if (length > decompressed.Length) { length = decompressed.Length; } length = Math.Min(length, decompressed.Length - segmentOffset); Array.Copy(decompressed, segmentOffset, data, 0, length); return(data); }
public resource_tag_stream(CacheFileGen3 c, DatumIndex tag, IO.EndianReader s) { cache = c; tag_datum = tag; InputStream = s; }
public static rTexture FromDDSImage(DDSImage image, string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) { // Create a new texture we can populate with info. rTexture texture = new rTexture(fileName, datum, fileType, isBigEndian); // Fill out the header fields. texture.header.Magic = rTextureHeader.kMagic; texture.header.Version = rTextureHeader.kVersion; texture.header.Width = image.Width; texture.header.Height = image.Height; texture.header.MipMapCount = (byte)image.MipMapCount; texture.header.Depth = image.Depth; // Check various flags to determine what type of texture this is. if (image.Flags.HasFlag(DDSD_FLAGS.DDSD_DEPTH) == true) { // Set the depthmap texture type. texture.header.TextureType = TextureType.Type_DepthMap; // Copy the DDS header from the image. texture.depthMapHeader = image.header; } else if (image.Capabilities2.HasFlag(DDSCAPS2.DDSCAPS2_CUBEMAP_ALLFACES) == true) { texture.header.TextureType = TextureType.Type_CubeMap; } else { texture.header.TextureType = TextureType.Type_2D; } // Check the image's fourcc code to determine the texture format. if (image.Format == 0) { // Check the bit count and color masks to determine the texture format. if (image.header.ddspf.dwFlags.HasFlag(DDPF.DDPF_BUMPDUDV) == true || (image.BitCount == 16 && image.RBitMask == 0xFF && image.GBitMask == 0xFF00)) { texture.header.Format = TextureFormat.Format_R8G8_SNORM; } else if (image.BitCount == 32) { texture.header.Format = TextureFormat.Format_B8G8R8A8_UNORM; } // TODO: Do we need to re-encode? } else { // Use the fourcc code to determine the texture format. texture.header.Format = DDSImage.TextureFormatFromFourCC(image.Format); } // Set the number of faces this texture has based on the texture type. if (texture.header.TextureType == TextureType.Type_CubeMap) { // Cubemap has 6 faces each with n mip map levels. texture.FaceCount = 6; } else { // All other texture types have 1 face with n mip maps. texture.FaceCount = 1; } // Calculate the total size of the pixel buffer. int pixelBufferSize = CalculatePixelBufferSize(texture.header.Width, texture.header.Height, texture.FaceCount, texture.header.MipMapCount, texture.header.Format, texture.header.TextureType); // Check if we need to pad the pixel buffer from the DDS image. byte[] pixelBuffer = image.PixelBuffer; if (pixelBufferSize > image.PixelBuffer.Length) { // Allocate a new array that is the correct size. pixelBuffer = new byte[pixelBufferSize]; // Copy in the pixel buffer from the DDS image and pad the remaining bytes. Array.Copy(image.PixelBuffer, pixelBuffer, image.PixelBuffer.Length); for (int i = image.PixelBuffer.Length; i < pixelBufferSize; i++) { pixelBuffer[i] = 0xCD; } } // Create the datastream using the pixel buffer we prepared. texture.PixelDataStream = DataStream.Create(pixelBuffer, true, false); // Make sure we are at the start of the pixel data stream. texture.PixelDataStream.Seek(0, SeekOrigin.Begin); // Allocate the sub resources array and setup for every face the texture has. texture.SubResources = new DataBox[texture.FaceCount * texture.header.MipMapCount]; for (int i = 0; i < texture.FaceCount; i++) { // Loop for the number of mip maps and read each one. for (int x = 0; x < texture.header.MipMapCount; x++) { int bytesPerRow = 0; int numberOfBlocks = 0; // Calculate the pitch values for the current mip level. int mipHeight = texture.header.TextureType == TextureType.Type_CubeMap ? texture.header.Width : texture.header.Height; CalculateMipMapPitch(texture.header.Width, mipHeight, x, texture.header.Format, out bytesPerRow, out numberOfBlocks); // Setup the resource description for this mip map. texture.SubResources[(i * texture.header.MipMapCount) + x] = new DataBox(texture.PixelDataStream.PositionPointer, bytesPerRow, bytesPerRow * numberOfBlocks); texture.PixelDataStream.Seek(bytesPerRow * numberOfBlocks, SeekOrigin.Current); } } // Return the texture. return(texture); }
public static rTexture FromGameResource(byte[] buffer, string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) { // Make sure the buffer is large enough to contain the texture header. if (buffer.Length < rTextureHeader.kSizeOf) { return(null); } // Create a new texture object to populate with data. rTexture texture = new rTexture(fileName, datum, fileType, isBigEndian); // Create a new memory stream and binary reader for the buffer. MemoryStream ms = new MemoryStream(buffer); EndianReader reader = new EndianReader(isBigEndian == true ? Endianness.Big : Endianness.Little, ms); // Parse the header. texture.header = new rTextureHeader(); texture.header.Magic = reader.ReadInt32(); texture.header.Version = reader.ReadByte(); texture.header.TextureType = (TextureType)reader.ReadByte(); texture.header.Flags = (TextureFlags)reader.ReadByte(); texture.header.MipMapCount = reader.ReadByte(); texture.header.Width = reader.ReadInt32(); texture.header.Height = reader.ReadInt32(); texture.header.Depth = reader.ReadInt32(); int fourcc = reader.ReadInt32(); texture.header.Format = TextureFormatFromFourCC(fourcc); texture.Swizzled = IsXboxFormat(fourcc); texture.XboxFormat = IsXboxFormat(fourcc); // Verify the magic is correct. if (texture.header.Magic != rTextureHeader.kMagic) { // Header has invalid magic. return(null); } // Check the version is supported. if (texture.header.Version != rTextureHeader.kVersion) { // Texture is an unsupported version. return(null); } // Make sure the texture format is supported. if (texture.header.Format == TextureFormat.Format_Unsupported) { // Texture is unsupported format. return(null); } // Check if we need to read the background color. if (texture.header.Flags.HasFlag(TextureFlags.HasD3DClearColor) == true) { // Read the RGBA background color. texture.BackgroundColor[0] = reader.ReadSingle(); texture.BackgroundColor[1] = reader.ReadSingle(); texture.BackgroundColor[2] = reader.ReadSingle(); texture.BackgroundColor[3] = reader.ReadSingle(); } // Check for some unknown blob. if (texture.header.TextureType == TextureType.Type_CubeMap) { // Read 108 bytes. // These could be vertex coordinates for 9 vertices that make up the box the cubemap gets rendered on? texture.cubemapData = reader.ReadBytes(108); } // TODO: Properly handle tiling on xbox 360 textures. //if (texture.Swizzled == true) //{ // //pixelData = Swizzle.ConvertToLinearTexture(pixelData, texture.header.Width, texture.header.Height, texture.header.Format); // int rowPitch = ((texture.header.Width + 3) / 4);// * RowPitchFromTextureFormat(texture.header.Format); // pixelData = Swizzle.XGUntileTextureLevel((uint)texture.header.Width, (uint)texture.header.Height, 0, texture.header.Format, // Swizzle.XGTILE.XGTILE_BORDER, (uint)rowPitch, null, pixelData, null); //} // If the texture type is a raw DDS file read the DDS header now. if (texture.header.TextureType == TextureType.Type_DepthMap) { // Read the DDS image header. texture.depthMapHeader = new DDS_HEADER(); texture.depthMapHeader.dwMagic = reader.ReadInt32(); texture.depthMapHeader.dwSize = reader.ReadInt32(); texture.depthMapHeader.dwFlags = (DDSD_FLAGS)reader.ReadInt32(); texture.depthMapHeader.dwHeight = reader.ReadInt32(); texture.depthMapHeader.dwWidth = reader.ReadInt32(); texture.depthMapHeader.dwPitchOrLinearSize = reader.ReadInt32(); texture.depthMapHeader.dwDepth = reader.ReadInt32(); texture.depthMapHeader.dwMipMapCount = reader.ReadInt32(); reader.BaseStream.Position += sizeof(int) * 11; texture.depthMapHeader.ddspf = new DDS_PIXELFORMAT(); texture.depthMapHeader.ddspf.dwSize = reader.ReadInt32(); texture.depthMapHeader.ddspf.dwFlags = (DDPF)reader.ReadInt32(); texture.depthMapHeader.ddspf.dwFourCC = reader.ReadInt32(); texture.depthMapHeader.ddspf.dwRGBBitCount = reader.ReadInt32(); texture.depthMapHeader.ddspf.dwRBitMask = reader.ReadUInt32(); texture.depthMapHeader.ddspf.dwGBitMask = reader.ReadUInt32(); texture.depthMapHeader.ddspf.dwBBitMask = reader.ReadUInt32(); texture.depthMapHeader.ddspf.dwABitMask = reader.ReadUInt32(); texture.depthMapHeader.dwCaps = (DDSCAPS)reader.ReadInt32(); texture.depthMapHeader.dwCaps2 = (DDSCAPS2)reader.ReadInt32(); texture.depthMapHeader.dwCaps3 = reader.ReadInt32(); texture.depthMapHeader.dwCaps4 = reader.ReadInt32(); reader.BaseStream.Position += sizeof(int); // BUG: need to check for dx10 header. // Check the header magic and structure sizes for sanity. if (texture.depthMapHeader.dwMagic != DDS_HEADER.kMagic || texture.depthMapHeader.dwSize != DDS_HEADER.kSizeOf || texture.depthMapHeader.ddspf.dwSize != DDS_PIXELFORMAT.kSizeOf) { // DDS header is invalid. return(null); } } // Read all of the pixel data now and pin it so we can build the sub resources array. byte[] pixelData = reader.ReadBytes((int)(reader.BaseStream.Length - reader.BaseStream.Position)); texture.PixelDataStream = DataStream.Create(pixelData, true, false); // Make sure we are at the start of the pixel data stream. texture.PixelDataStream.Seek(0, SeekOrigin.Begin); // Set the number of faces this texture has based on the texture type. if (texture.header.TextureType == TextureType.Type_CubeMap) { // Cubemap has 6 faces each with n mip map levels. texture.FaceCount = 6; } else { // All other texture types have 1 face with n mip maps. texture.FaceCount = 1; } // Allocate the sub resources array and setup for every face the texture has. texture.SubResources = new DataBox[texture.FaceCount * texture.header.MipMapCount]; for (int i = 0; i < texture.FaceCount; i++) { // Loop for the number of mip maps and read each one. for (int x = 0; x < texture.header.MipMapCount; x++) { int bytesPerRow = 0; int numberOfBlocks = 0; // Calculate the pitch values for the current mip level. int mipHeight = texture.header.TextureType == TextureType.Type_CubeMap ? texture.header.Width : texture.header.Height; CalculateMipMapPitch(texture.header.Width, mipHeight, x, texture.header.Format, out bytesPerRow, out numberOfBlocks); // Setup the resource description for this mip map. texture.SubResources[(i * texture.header.MipMapCount) + x] = new DataBox(texture.PixelDataStream.PositionPointer, bytesPerRow, bytesPerRow * numberOfBlocks); texture.PixelDataStream.Seek(bytesPerRow * numberOfBlocks, SeekOrigin.Current); } } // Close the binary reader and memory stream. reader.Close(); ms.Close(); // Return the texture object. return(texture); }
public rTexture(string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) : base(fileName, datum, fileType, isBigEndian) { }
/// <summary> /// Initializes a new instance of the <see cref="DataBlockResourceFixup" /> class. /// </summary> /// <param name="originalIndex">The original datum index of the resouce.</param> /// <param name="writeOffset">The offset within the data block's data to write the new datum index of the resource to.</param> public DataBlockResourceFixup(DatumIndex originalIndex, int writeOffset) { OriginalIndex = originalIndex; WriteOffset = writeOffset; }
public static XmlFile FromGameResource(byte[] buffer, string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) { // Create a new XmlFile from the resource buffer. return(new XmlFile(buffer, fileName, datum, fileType, isBigEndian)); }
public void WriteExpression(DatumIndex expressionIndex, IndentedTextWriter output) { WriteExpression(_scripts.Expressions.FindExpression(expressionIndex), output); }
public TI.Definition LoadResources(DatumIndex resource, CacheFileGen3 c, cache_file_resource_layout_table cache_layout) { return(LoadResources(resource, c, cache_layout, false)); }
public override byte[] GetSecondaryResource(DatumIndex ID, int dataLength, int offset = 0, bool padding = false) { if (ID == DatumIndex.None) { return(null); } if (ResourceLayoutTable == null || ResourceGestalt == null) { LoadResourceTags(); } var resource = ResourceGestalt.TagResources[ID.Index]; if (resource.SegmentIndex == -1) { return(null); } var segment = ResourceLayoutTable.Segments[resource.SegmentIndex]; if (segment.OptionalPageIndex == -1 || segment.OptionalSegmentOffset == -1) { return(null); } int pageIndex = segment.OptionalPageIndex; int segmentOffset = segment.OptionalSegmentOffset + offset; if (pageIndex == -1 || segmentOffset == -1) { return(null); } if (ResourceLayoutTable.RawPages[pageIndex].BlockOffset == -1) { return(null); } var page = ResourceLayoutTable.RawPages[pageIndex]; var decompressed = ReadPageData(resource, page); var length = dataLength; var data = new byte[length]; if (length > decompressed.Length || (length + segmentOffset) > decompressed.Length) { if (padding) { length = decompressed.Length; if (length + segmentOffset > decompressed.Length) { length = decompressed.Length - segmentOffset; } } else { return(null); } } Array.Copy(decompressed, segmentOffset, data, 0, length); return(data); }
protected override BlamLib.Managers.CacheTagDatabase CreateCacheTagDatabaseInternal(DatumIndex cache_id) { return new Halo1.Tags.CacheTagDatabase((Halo1.CacheFile)Program.GetCacheFile(cache_id)); }
private static BitmapTextureInterleavedInteropResource GetInterleavedResourceDefinition(CacheFile cache, DatumIndex handle) { var resourceEntry = cache.ResourceGestalt.TagResources[handle.Index]; var definitionData = cache.ResourceGestalt.FixupInformation.Skip(resourceEntry.FixupInformationOffset).Take(resourceEntry.FixupInformationLength).ToArray(); BitmapTextureInterleavedInteropResource definition; using (var definitionStream = new MemoryStream(definitionData, true)) using (var definitionReader = new EndianReader(definitionStream, EndianFormat.BigEndian)) using (var definitionWriter = new EndianWriter(definitionStream, EndianFormat.BigEndian)) { foreach (var fixup in resourceEntry.ResourceFixups) { var newFixup = new TagResourceGen3.ResourceFixup { BlockOffset = (uint)fixup.BlockOffset, Address = new CacheAddress(CacheAddressType.Definition, fixup.Offset) }; definitionStream.Position = newFixup.BlockOffset; definitionWriter.Write(newFixup.Address.Value); } var dataContext = new DataSerializationContext(definitionReader, definitionWriter, CacheAddressType.Definition); definitionStream.Position = resourceEntry.DefinitionAddress.Offset; definition = cache.Deserializer.Deserialize <BitmapTextureInterleavedInteropResource>(dataContext); } return(definition); }
/// <summary> /// Activates or deactivates a tag in the zone set. /// </summary> /// <param name="index">The datum index of the tag to activate or deactivate.</param> /// <param name="activate"><c>true</c> if the tag should be made active, <c>false</c> otherwise.</param> public void ActivateTag(DatumIndex index, bool activate) { _activeTags.Length = Math.Max(_activeTags.Length, index.Index + 1); _activeTags[index.Index] = activate; }
private void Load(StructureValueCollection values) { Name = values.GetString("name"); Type = (short)values.GetInteger("type"); ExpressionIndex = new DatumIndex(values.GetInteger("expression index")); }
protected override Managers.CacheTagDatabase CreateCacheTagDatabaseInternal(DatumIndex cache_id) { return(new Halo2.Tags.CacheTagDatabase((Halo2.CacheFile)Program.GetCacheFile(cache_id))); }
public override object Execute(List <string> args) { if (args.Count > 1) { return(false); } var PortTagCommand = new Porting.PortTagCommand(CacheContext, null); var csvFileName = "scriptsDumpOutput.csv"; foreach (var a in args) { if (a.Contains(".") || a.Contains(".")) { csvFileName = a; } } csvQueue1 = new List <string>(); var globals = new Dictionary <DatumIndex, string>(); var i = -1; CsvAdd("Globals"); foreach (var a in Definition.Globals) { i++; var salt = a.InitializationExpressionHandle.Salt; CsvAdd( $"{i:D4}," + $"{i:X4}," + $"{a.InitializationExpressionHandle:X8}," + $"{salt:X4}," + $"{a.Name,-0x20}," + $"{a.Type.HaloOnline}," + $""); globals.Add(a.InitializationExpressionHandle, a.Name); } CsvAdd("Scripts"); foreach (var script in Definition.Scripts) { CsvAdd($"{Definition.Scripts.IndexOf(script):D4}," + $"{Definition.Scripts.IndexOf(script):X4}," + $"{script.Type.ToString()}," + $"{script.ReturnType.HaloOnline}," + $"{script.ScriptName}," + $"A:{script.RootExpressionHandle:X8}"); } var failedOpcodes = new Dictionary <int, int>(); i = -1; foreach (var expr in Definition.ScriptExpressions) { i++; if (expr.Opcode == 0xBABA) { continue; } var scriptGroupName = ""; if (expr.NextExpressionHandle == DatumIndex.None && expr.Flags == Scripting.HsSyntaxNodeFlags.Group && expr.Opcode == 0x0) { var ScriptGroupName = Definition.Scripts.Find(x => x.RootExpressionHandle.Salt == expr.Identifier); if (ScriptGroupName != null) { scriptGroupName = $",S:{ScriptGroupName.ScriptName}"; } } var ExpressionHandle = new DatumIndex((uint)((expr.Identifier << 16) + i)); if (globals.ContainsKey(ExpressionHandle)) { scriptGroupName = $"G:{globals[ExpressionHandle]}"; } var opcodeName = ""; if (PortTagCommand.ScriptExpressionIsValue(expr)) { if (Scripting.ScriptInfo.ValueTypes[CacheVersion.HaloOnline106708].ContainsKey(expr.Opcode)) { opcodeName = $"{Scripting.ScriptInfo.ValueTypes[CacheVersion.HaloOnline106708][expr.Opcode]},value"; } } else { if (Scripting.ScriptInfo.Scripts[CacheVersion.HaloOnline106708].ContainsKey(expr.Opcode)) { opcodeName = Scripting.ScriptInfo.Scripts[CacheVersion.HaloOnline106708][expr.Opcode].Name; } } if (expr.Flags == Scripting.HsSyntaxNodeFlags.ScriptReference) { opcodeName = ""; } if (i > 0 && Definition.ScriptExpressions[i - 1].Flags == Scripting.HsSyntaxNodeFlags.ScriptReference) { opcodeName = ""; } var ValueType = ""; ValueType = expr.ValueType.HaloOnline.ToString(); CsvAdd( $"{i:D8}," + $"{((expr.Identifier << 16) | i):X8}," + $"{expr.NextExpressionHandle.Value:X8}," + $"{expr.Opcode:X4}," + $"{expr.Data[0]:X2}" + $"{expr.Data[1]:X2}" + $"{expr.Data[2]:X2}" + $"{expr.Data[3]:X2}," + $"{expr.Flags}," + $"{ValueType}," + $"{opcodeName}," + $"{scriptGroupName}" + $""); } CsvDumpQueueToFile(csvQueue1, csvFileName); return(true); }
private static ExtractedResourceInfo ReadResource(IReader reader, byte version) { if (version > 2) { throw new InvalidOperationException("Unrecognized \"rsrc\" block version"); } var originalIndex = new DatumIndex(reader.ReadUInt32()); var resource = new ExtractedResourceInfo(originalIndex); resource.Flags = reader.ReadUInt32(); resource.Type = reader.ReadAscii(); if (string.IsNullOrEmpty(resource.Type)) { resource.Type = null; } resource.Info = ReadByteArray(reader); resource.OriginalParentTagIndex = new DatumIndex(reader.ReadUInt32()); byte hasLocation = reader.ReadByte(); if (hasLocation != 0) { resource.Location = new ExtractedResourcePointer(); resource.Location.OriginalPrimaryPageIndex = reader.ReadInt32(); resource.Location.PrimaryOffset = reader.ReadInt32(); if (version > 1) { var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.PrimarySize = newSize; } else { resource.Location.PrimarySize = null; } } else { resource.Location.PrimarySize = null; reader.Skip(4); } resource.Location.OriginalSecondaryPageIndex = reader.ReadInt32(); resource.Location.SecondaryOffset = reader.ReadInt32(); if (version > 1) { var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.SecondarySize = newSize; } else { resource.Location.SecondarySize = null; } } else { resource.Location.SecondarySize = null; reader.Skip(4); } if (version > 1) { resource.Location.OriginalTertiaryPageIndex = reader.ReadInt32(); resource.Location.TertiaryOffset = reader.ReadInt32(); var size = reader.ReadInt32(); if (size != -1) { ResourceSize newSize = new ResourceSize(); newSize.Size = size; byte partCount = reader.ReadByte(); for (int i = 0; i < partCount; i++) { ResourceSizePart newPart = new ResourceSizePart(); newPart.Offset = reader.ReadInt32(); newPart.Size = reader.ReadInt32(); newSize.Parts.Add(newPart); } resource.Location.TertiarySize = newSize; } else { resource.Location.TertiarySize = null; } } } if (version == 1) { reader.BaseStream.Position += 4; resource.ResourceBits = reader.ReadUInt16(); reader.BaseStream.Position += 2; } else { resource.ResourceBits = reader.ReadInt32(); } resource.BaseDefinitionAddress = reader.ReadInt32(); int numResourceFixups = reader.ReadInt32(); for (int i = 0; i < numResourceFixups; i++) { var fixup = new ResourceFixup(); fixup.Offset = reader.ReadInt32(); fixup.Address = reader.ReadUInt32(); resource.ResourceFixups.Add(fixup); } int numDefinitionFixups = reader.ReadInt32(); for (int i = 0; i < numDefinitionFixups; i++) { var fixup = new ResourceDefinitionFixup(); fixup.Offset = reader.ReadInt32(); fixup.Type = reader.ReadInt32(); resource.DefinitionFixups.Add(fixup); } return(resource); }
public rMotionList(string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) : base(fileName, datum, fileType, isBigEndian) { }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Loads a structure bsp. </summary> /// /// <param name="path"> Tags relative pathname of the bsp tag. </param> /// /// <returns> The loaded structure bsp. </returns> structure_bsp_group LoadStructureBSP(string tagsDirectory, string path) { // Load the structure bsp var tagsPath = new BlamPath(tagsDirectory); mTagHandler = new TagIndexHandler<BlamLib.Managers.TagIndex>(BlamLib.BlamVersion.Halo1_CE, tagsPath.Root); mBSPDatumIndex = mTagHandler.IndexInterface.Open(path, BlamLib.Blam.Halo1.TagGroups.sbsp); if (!BlamLib.Managers.TagIndex.IsValid(mBSPDatumIndex)) { SendMessage("Failed to load the target BSP"); return null; } var tagManager = mTagHandler.IndexInterface[mBSPDatumIndex]; var structureBSP = tagManager.TagDefinition as structure_bsp_group; if (structureBSP == null) { SendMessage("Failed to load the target BSP"); return null; } return structureBSP; }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="rootPath"> The users HEK root directory. </param> public LightmapImporter() { mTagHandler = null; mBSPDatumIndex = DatumIndex.Null; }
private bool GenerateGroup(ScriptExpression expression, IndentedTextWriter output) { var childIndex = new DatumIndex(expression.Value); if (!childIndex.IsValid) throw new InvalidOperationException("Group expression has no child"); GenerateCode(_scripts.Expressions.FindExpression(childIndex), output); return true; }
public void SavePredictions(ICollection <ResourcePredictionD> predictions, IStream stream) { StructureValueCollection values = LoadTag(stream); FreePredictions(values); var dentries = new List <StructureValueCollection>(); var centries = new List <StructureValueCollection>(); var bentries = new List <StructureValueCollection>(); var aentries = new List <StructureValueCollection>(); var writtenc = new Dictionary <long, int>(); //hash, index var writtenb = new Dictionary <long, int>(); int firstnullc = -1; DatumIndex currenttag = DatumIndex.Null; foreach (ResourcePredictionD pred in predictions) { long dchash = pred.GetCHash(); int dcstart = centries.Count(); int dastart = aentries.Count; if (pred.CEntries.Count > 0) { int exist; bool found = writtenc.TryGetValue(dchash, out exist); if (!found) { foreach (ResourcePredictionC pc in pred.CEntries) { long cbhash = pc.GetBHash(); int cbstart = bentries.Count; int bexist; bool bfound = writtenb.TryGetValue(cbhash, out bexist); if (!bfound) { int bkstart = aentries.Count(); foreach (ResourcePredictionA pa in pc.BEntry.AEntries) { aentries.Add(SerializePredictionA(pa, stream)); } writtenb[cbhash] = cbstart; bentries.Add(SerializePredictionB(pc.BEntry, bkstart, cbstart, stream)); } else { cbstart = bexist; } writtenc[dchash] = dcstart; centries.Add(SerializePredictionC(pc, cbstart, cbstart, stream)); } } else { dcstart = exist; } } else { if (firstnullc == -1) { firstnullc = dcstart; } else { dcstart = firstnullc; } } if (pred.AEntries.Count > 0) { foreach (ResourcePredictionA pa in pred.AEntries) { aentries.Add(SerializePredictionA(pa, stream)); } } else { dastart = -1; } dentries.Add(SerializePredictionD(pred, dcstart, dastart, stream)); } // a StructureLayout alayout = _buildInfo.Layouts.GetLayout("prediction a entry"); long newa = ReflexiveWriter.WriteReflexive(aentries, alayout, _metaArea, _allocator, stream); uint conta = _expander.Contract(newa); values.SetInteger("number of prediction as", (uint)aentries.Count); values.SetInteger("prediction a table address", conta); // b StructureLayout blayout = _buildInfo.Layouts.GetLayout("prediction b entry"); long newb = ReflexiveWriter.WriteReflexive(bentries, blayout, _metaArea, _allocator, stream); uint contb = _expander.Contract(newb); values.SetInteger("number of prediction bs", (uint)bentries.Count); values.SetInteger("prediction b table address", contb); // cc StructureLayout clayout = _buildInfo.Layouts.GetLayout("prediction c entry"); long newc = ReflexiveWriter.WriteReflexive(centries, clayout, _metaArea, _allocator, stream); uint contc = _expander.Contract(newc); values.SetInteger("number of prediction cs", (uint)centries.Count); values.SetInteger("prediction c table address", contc); // d StructureLayout dlayout = _buildInfo.Layouts.GetLayout("prediction d entry"); long newd = ReflexiveWriter.WriteReflexive(dentries, dlayout, _metaArea, _allocator, stream); uint contd = _expander.Contract(newd); values.SetInteger("number of prediction ds", (uint)dentries.Count); values.SetInteger("prediction d table address", contd); // d2 StructureLayout d2layout = _buildInfo.Layouts.GetLayout("prediction d2 entry"); long newd2 = ReflexiveWriter.WriteReflexive(dentries, d2layout, _metaArea, _allocator, stream); uint contd2 = _expander.Contract(newd2); values.SetInteger("number of prediction d2s", (uint)dentries.Count); values.SetInteger("prediction d2 table address", contd2); SaveTag(values, stream); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Constructor. </summary> /// /// <param name="game"> The game engine version. </param> /// <param name="path"> Full pathname of the tags root directory. </param> /// <param name="tags_dir"> (Optional) the tags folder name. </param> public TagIndexHandler(BlamVersion game, string path, string tags_dir = "tags") { mGameVersion = game; mIndexHandle = BlamLib.Program.GetManager(mGameVersion).OpenTagIndex(game, path, tags_dir); mIndexInterface = BlamLib.Program.GetTagIndex(mIndexHandle) as T; }
private Resource LoadResource(StructureValueCollection values, int index, TagTable tags, IList <ResourcePointer> pointers, byte[] infoBuffer, IReader reader) { var result = new Resource(); var parentTag = new DatumIndex(values.GetInteger("parent tag datum index")); result.ParentTag = parentTag.IsValid ? tags[parentTag] : null; var salt = (ushort)values.GetInteger("datum index salt"); result.Index = new DatumIndex(salt, (ushort)index); var typeIndex = (int)values.GetInteger("resource type index"); if (typeIndex >= 0 && typeIndex < _resourceTypes.Length) { result.Type = _resourceTypes[typeIndex].Name; } result.Flags = (uint)values.GetInteger("flags"); var infoSize = (int)values.GetInteger("resource info size"); if (infoSize > 0) { var infoOffset = 0; if (values.HasInteger("number of resource info offsets")) //for h4 { var infocount = (int)values.GetInteger("number of resource info offsets"); uint address = (uint)values.GetInteger("resource info offsets table address"); long expand = _expander.Expand(address); StructureLayout layout = _buildInfo.Layouts.GetLayout("resource info offset entry"); StructureValueCollection[] entries = ReflexiveReader.ReadReflexive(reader, infocount, expand, layout, _metaArea); if (infocount > 0) { infoOffset = (int)entries[0].GetInteger("offset"); } } else { infoOffset = (int)values.GetInteger("resource info offset"); } // Copy the section of the info buffer that the resource is pointing to result.Info = new byte[infoSize]; Buffer.BlockCopy(infoBuffer, infoOffset, result.Info, 0, infoSize); } result.ResourceBits = (ushort)values.GetInteger("resource bits"); var segmentIndex = (int)values.GetInteger("segment index"); result.Location = (segmentIndex >= 0) ? pointers[segmentIndex] : null; result.BaseDefinitionAddress = (int)values.GetInteger("base definition address"); result.ResourceFixups.AddRange(LoadResourceFixups(values, reader)); result.DefinitionFixups.AddRange(LoadDefinitionFixups(values, reader)); return(result); }
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); } }
public DatumIndex Add(DatumIndex source_index_tag_index) { Managers.TagManager tagman = sourceIndex[source_index_tag_index]; return(BuildFromSource(tagman).Datum); }
private Resource LoadResource(StructureValueCollection values, int index, TagTable tags, IList<ResourcePointer> pointers, byte[] infoBuffer, IReader reader) { var result = new Resource(); var parentTag = new DatumIndex(values.GetInteger("parent tag datum index")); result.ParentTag = parentTag.IsValid ? tags[parentTag] : null; var salt = (ushort) values.GetInteger("datum index salt"); result.Index = new DatumIndex(salt, (ushort) index); var typeIndex = (int) values.GetInteger("resource type index"); if (typeIndex >= 0 && typeIndex < _resourceTypes.Length) result.Type = _resourceTypes[typeIndex].Name; result.Flags = values.GetInteger("flags"); var infoOffset = (int) values.GetInteger("resource info offset"); var infoSize = (int) values.GetInteger("resource info size"); if (infoSize > 0) { // Copy the section of the info buffer that the resource is pointing to result.Info = new byte[infoSize]; Buffer.BlockCopy(infoBuffer, infoOffset, result.Info, 0, infoSize); } result.Unknown1 = (int) values.GetInteger("unknown 1"); result.Unknown2 = (int) values.GetInteger("unknown 2"); var segmentIndex = (int) values.GetInteger("segment index"); result.Location = (segmentIndex >= 0) ? pointers[segmentIndex] : null; result.Unknown3 = (int) values.GetInteger("unknown 3"); result.ResourceFixups.AddRange(LoadResourceFixups(values, reader)); result.DefinitionFixups.AddRange(LoadDefinitionFixups(values, reader)); return result; }
protected BuilderItem(BuilderTagIndexBase owner, Managers.TagManager source) { this.sourceIndexDatum = source.TagIndex; this.groupTag = source.GroupTag; this.referenceName = Managers.ReferenceManager.CopyHandle(/*this,*/ owner.References, owner.SourceIndex.References, source.ReferenceName); }
/// <summary> /// Determines whether or not a tag is marked as active. /// </summary> /// <param name="index">The datum index of the tag to check.</param> /// <returns><c>true</c> if the tag is active, <c>false</c> otherwise.</returns> public bool IsTagActive(DatumIndex index) { if (index.Index >= _activeTags.Count) return false; return _activeTags[index.Index]; }
bool BlamLib.Managers.IReferenceMangerObject.UpdateReferenceId(BlamLib.Managers.ReferenceManager manager, DatumIndex new_datum) { this.referenceName = new_datum; return(true); }
/// <summary> /// Determines whether or not a resource is marked as active. /// </summary> /// <param name="index">The datum index of the resource to check.</param> /// <returns><c>true</c> if the resource is active, <c>false</c> otherwise.</returns> public bool IsResourceActive(DatumIndex index) { if (index.Index >= _activeResources.Count) return false; return _activeResources[index.Index]; }
public static byte[] GetXMAData(CacheFile cache, DatumIndex handle, int size) { return(cache.GetSoundRaw(handle, size)); }
public static rMotionList FromGameResource(byte[] buffer, string fileName, DatumIndex datum, ResourceType fileType, bool isBigEndian) { // Make sure the buffer is large enough to hold the header. if (buffer.Length < rMotionListHeader.kSizeOf) { return(null); } // Create a new motion list to populate with info. rMotionList motion = new rMotionList(fileName, datum, fileType, isBigEndian); // Create a new memory stream and binary reader for the buffer. MemoryStream ms = new MemoryStream(buffer); EndianReader reader = new EndianReader(isBigEndian == true ? Endianness.Big : Endianness.Little, ms); // Parse the header. motion.header.Magic = reader.ReadInt32(); motion.header.Version = reader.ReadInt16(); motion.header.AnimationCount = reader.ReadInt16(); // Check the header magic and version. if (motion.header.Magic != rMotionListHeader.kMagic || motion.header.Version != rMotionListHeader.kVersion) { // Header magic or version are invalid or unsupported. return(null); } // Read all of the animation descriptor offsets. int[] animationDescriptorOffsets = new int[motion.header.AnimationCount]; for (int i = 0; i < motion.header.AnimationCount; i++) { animationDescriptorOffsets[i] = reader.ReadInt32(); reader.BaseStream.Position += 4; } // Loop through all of the animation descriptors and read each one. motion.animations = new AnimationDescriptor[motion.header.AnimationCount]; for (int i = 0; i < motion.header.AnimationCount; i++) { // Check if this animation is used. if (animationDescriptorOffsets[i] == 0) { continue; } // Seek to the next descriptor and read it. reader.BaseStream.Position = animationDescriptorOffsets[i]; motion.animations[i].KeyFrameDataOffset = reader.ReadInt32(); reader.BaseStream.Position += 4; motion.animations[i].JointCount = reader.ReadInt32(); motion.animations[i].FrameCount = reader.ReadInt32(); motion.animations[i].LoopFrame = reader.ReadInt32(); motion.animations[i].Unk1 = reader.ReadInt32(); motion.animations[i].Unk2 = reader.ReadInt32(); motion.animations[i].Unk3 = reader.ReadInt32(); motion.animations[i].Translation = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); motion.animations[i].Unk4 = reader.ReadInt32(); motion.animations[i].Unk5 = reader.ReadInt32(); motion.animations[i].Unk6 = reader.ReadInt32(); motion.animations[i].Unk7 = reader.ReadInt32(); motion.animations[i].Unk8 = reader.ReadInt32(); motion.animations[i].Unk9 = reader.ReadInt32(); motion.animations[i].Unk10 = reader.ReadInt32(); motion.animations[i].Unk11 = reader.ReadInt32(); motion.animations[i].Unk12 = reader.ReadInt32(); motion.animations[i].Unk13 = reader.ReadInt32(); motion.animations[i].Unk14 = reader.ReadInt32(); motion.animations[i].Unk15 = reader.ReadInt32(); motion.animations[i].Unk16 = reader.ReadInt32(); motion.animations[i].Unk17 = reader.ReadInt32(); motion.animations[i].Unk18 = reader.ReadInt32(); motion.animations[i].Unk19 = reader.ReadInt32(); motion.animations[i].Count1 = reader.ReadInt32(); reader.BaseStream.Position += 4; motion.animations[i].Offset1 = reader.ReadInt32(); reader.BaseStream.Position += 4; motion.animations[i].Unk20 = reader.ReadSingle(); motion.animations[i].Unk21 = reader.ReadSingle(); motion.animations[i].Unk22 = reader.ReadSingle(); motion.animations[i].Unk23 = reader.ReadSingle(); motion.animations[i].Unk24 = reader.ReadSingle(); motion.animations[i].Unk25 = reader.ReadSingle(); motion.animations[i].Unk26 = reader.ReadSingle(); motion.animations[i].Unk27 = reader.ReadSingle(); motion.animations[i].Unk28 = reader.ReadSingle(); motion.animations[i].Unk29 = reader.ReadSingle(); motion.animations[i].Unk30 = reader.ReadSingle(); motion.animations[i].Unk31 = reader.ReadSingle(); motion.animations[i].Unk32 = reader.ReadSingle(); motion.animations[i].Unk33 = reader.ReadSingle(); motion.animations[i].Unk34 = reader.ReadSingle(); motion.animations[i].Unk35 = reader.ReadSingle(); motion.animations[i].Count2 = reader.ReadInt32(); reader.BaseStream.Position += 4; motion.animations[i].Offset2 = reader.ReadInt32(); // Loop and read each key frame. motion.animations[i].KeyFrames = new KeyFrameDescriptor[motion.animations[i].JointCount]; for (int x = 0; x < motion.animations[i].JointCount; x++) { // Read the keyframe descriptor. reader.BaseStream.Position = motion.animations[i].KeyFrameDataOffset + (x * KeyFrameDescriptor.kSizeOf); motion.animations[i].KeyFrames[x].Codec = reader.ReadByte(); motion.animations[i].KeyFrames[x].Usage = reader.ReadByte(); motion.animations[i].KeyFrames[x].JointType = reader.ReadByte(); motion.animations[i].KeyFrames[x].JointIndex = reader.ReadByte(); motion.animations[i].KeyFrames[x].BlendWeight = reader.ReadSingle(); motion.animations[i].KeyFrames[x].DataSize = reader.ReadInt32(); reader.BaseStream.Position += 4; motion.animations[i].KeyFrames[x].DataOffset = reader.ReadInt32(); reader.BaseStream.Position += 4; // Save the current position. long position = reader.BaseStream.Position; // Allocate the key frame data array. int entrySizeForCode = KeyFrameDataSizeFromCodec(motion.animations[i].KeyFrames[x].Codec); motion.animations[i].KeyFrames[x].KeyFrameData = new KeyFrameData[motion.animations[i].KeyFrames[x].DataSize / entrySizeForCode]; // Seek to the start of the key frame data and read it. reader.BaseStream.Position = motion.animations[i].KeyFrames[x].DataOffset; for (int z = 0; z < motion.animations[i].KeyFrames[x].KeyFrameData.Length; z++) { // Check the codec type and handle accordingly. switch (motion.animations[i].KeyFrames[x].Codec) { case 1: case 2: // Uncompressed vector3 { motion.animations[i].KeyFrames[x].KeyFrameData[z].Component = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), 0.0f); break; } case 3: // Uncompressed vector3 w/ scale { float a = reader.ReadSingle(); float b = reader.ReadSingle(); float c = reader.ReadSingle(); motion.animations[i].KeyFrames[x].KeyFrameData[z].Component = new Vector4(a, b, c, (float)Math.Sqrt((a * a) + (b * b) + (c * c))); break; } case 4: // Uncompressed Vector3 w/ scale { float a = reader.ReadSingle(); float b = reader.ReadSingle(); float c = reader.ReadSingle(); float scale = 1 - ((a * a) + (b * b) + (c * c)); motion.animations[i].KeyFrames[x].KeyFrameData[z].Component = new Vector4(a, b, c, (float)Math.Sqrt(scale > 0.0f ? scale : 0.0f)); break; } case 6: // compressed vector3: 17/17/19 bit compressed vector3 + flags + duration { long compressedVec = reader.ReadInt64(); float a = (float)(compressedVec & 0x1FFFF) * 0.000011984317f; float b = (float)((compressedVec >> 17) & 0x1FFFF) * 0.000011984317f; float c = (float)((compressedVec >> 34) & 0x7FFFF) * 0.0000019073523f; // Note: I don't think this condition can exist since we mask 17 or 19 bits but // test the entire 64bit register. // If any of the packed values were negative recompute them. //if ((compressedVec & 0x1FFFF) < 0) // a = ((compressedVec & 0x1FFFF) + 0.000011984317f) * 0.000011984317f; motion.animations[i].KeyFrames[x].KeyFrameData[z].Component = new Vector4(a, b, a - 1.5707964f, b - 1.5707964f); motion.animations[i].KeyFrames[x].KeyFrameData[z].Scalar = c; motion.animations[i].KeyFrames[x].KeyFrameData[z].Flags = (byte)((compressedVec >> 53) & 7); motion.animations[i].KeyFrames[x].KeyFrameData[z].Duration = (byte)((compressedVec >> 56) & 0xFF); break; } default: { // Unsupported codec type. break; } } } } } // Close the binary reader and memory stream. reader.Close(); ms.Close(); // Return the motion list. return(motion); }
public ThirdGenTag(DatumIndex index, ITagClass tagClass, SegmentPointer metaLocation) { Index = index; Class = tagClass; MetaLocation = metaLocation; }
/// <summary> /// Looks up a resource by its datum index and returns it. /// </summary> /// <param name="index">The datum index of the resource to look up.</param> /// <returns>The resource with the corresponding index.</returns> public IResource this[DatumIndex index] { get { return _resources[index.Index]; } }
public IEnumerable <ResourcePredictionD> LoadPredictions(IReader reader, TagTable tags, List <Resource> resources) { StructureValueCollection values = LoadTag(reader); if (!values.HasInteger("number of prediction d2s") || !values.HasInteger("prediction d2 table address")) { return(null); } int subcount = 2; StructureLayout templayout = _buildInfo.Layouts.GetLayout("raw segment table entry"); if (templayout.HasField("tertiary page index")) { subcount = 3; } var result = new List <ResourcePredictionD>(); StructureValueCollection[] d2entries = ReadReflexive(values, reader, "number of prediction d2s", "prediction d2 table address", "prediction d2 entry"); StructureValueCollection[] dentries = ReadReflexive(values, reader, "number of prediction ds", "prediction d table address", "prediction d entry"); StructureValueCollection[] centries = ReadReflexive(values, reader, "number of prediction cs", "prediction c table address", "prediction c entry"); StructureValueCollection[] bentries = ReadReflexive(values, reader, "number of prediction bs", "prediction b table address", "prediction b entry"); StructureValueCollection[] aentries = ReadReflexive(values, reader, "number of prediction as", "prediction a table address", "prediction a entry"); for (int i = 0; i < d2entries.Length; i++) { ResourcePredictionD pd = new ResourcePredictionD(); pd.Index = i; var tag = new DatumIndex(d2entries[i].GetInteger("tag datum")); pd.Tag = tag.IsValid ? tags[tag] : null; pd.Unknown1 = (int)d2entries[i].GetInteger("unknown 1"); pd.Unknown2 = (int)d2entries[i].GetInteger("unknown 2"); var dccount = (int)dentries[i].GetInteger("c count"); var dcindex = (int)dentries[i].GetInteger("c index"); var dacount = (int)dentries[i].GetInteger("a count"); var daindex = (int)dentries[i].GetInteger("a index"); for (int c = dcindex; c < dcindex + dccount; c++) { ResourcePredictionC pc = new ResourcePredictionC(); pc.Index = c; var cbindex = (int)centries[c].GetInteger("b index"); pc.OverallIndex = (short)centries[c].GetInteger("overall index"); ResourcePredictionB pb = new ResourcePredictionB(); pb.Index = cbindex; var bacount = (int)bentries[cbindex].GetInteger("a count"); var baindex = (int)bentries[cbindex].GetInteger("a index"); pb.OverallIndex = (short)bentries[cbindex].GetInteger("overall index"); for (int a = baindex; a < baindex + bacount; a++) { ResourcePredictionA pa = new ResourcePredictionA(); pa.Index = a; pa.Value = new DatumIndex(aentries[a].GetInteger("value")); int resolvedresource = pa.Value.Index / subcount; int subresource = pa.Value.Index - resolvedresource * subcount; if (resolvedresource >= resources.Count) { continue; } var res = resources[resolvedresource]; pa.Resource = res.Index; pa.SubResource = subresource; pb.AEntries.Add(pa); } pc.BEntry = pb; pd.CEntries.Add(pc); } for (int a = daindex; a < daindex + dacount; a++) { ResourcePredictionA pa = new ResourcePredictionA(); pa.Index = a; pa.Value = new DatumIndex(aentries[a].GetInteger("value")); int resolvedresource = pa.Value.Index / subcount; int subresource = pa.Value.Index - resolvedresource * subcount; if (resolvedresource >= resources.Count) { continue; } var res = resources[resolvedresource]; pa.Resource = res.Index; pa.SubResource = subresource; pd.AEntries.Add(pa); } result.Add(pd); } return(result); }