public static byte[] GetResourceFromCache(this IResourceBlock blockInfo, int index = 0) { Stream source = null; var resourcePointer = blockInfo.GetResourcePointer(index); var resourceLength = blockInfo.GetResourceLength(index); if (resourcePointer.Source == Halo2.ResourceSource.Local) { source = ActiveCache as CacheStream; } if (resourcePointer.Source == Halo2.ResourceSource.Shared) { source = (Stream)Index.Caches.FirstOrDefault(IsCacheCalled("shared")); } if (resourcePointer.Source == Halo2.ResourceSource.SinglePlayerShared) { source = (Stream)Index.Caches.FirstOrDefault(IsCacheCalled("single_player_shared")); } if (resourcePointer.Source == Halo2.ResourceSource.MainMenu) { source = (Stream)Index.Caches.FirstOrDefault(IsCacheCalled("mainmenu")); } if (source == null) { return(null); } source.Position = resourcePointer.Address; var buffer = new byte[resourceLength]; source.Read(buffer, 0, resourceLength); return(buffer); }
public static void RebuildBlocks(IResourceBlock rootBlock) { var processed = new HashSet <IResourceBlock>(); void RebuildChildren(IResourceBlock block) { if (block is IResourceSystemBlock sblock) { if (processed.Add(block)) { var references = sblock.GetReferences(); foreach (var reference in references) { RebuildChildren(reference); } var parts = sblock.GetParts(); foreach (var part in parts) { RebuildChildren(part.Item2); } sblock.Rebuild(); } } } RebuildChildren(rootBlock); }
public LayerExtraRecordsX(LayerMaskBlock layerMask, LayerBlendingRangesBlock blendingRanges, LayerResourceBlock resources, string name) { this.layerMask = layerMask; this.blendingRanges = blendingRanges; this.resources = resources; this.name = name; IResourceBlock block = null; block = this.resources.Resources.FirstOrDefault(x => x is luniResource); if (block != null) { var luni = (luniResource)block; this.name = luni.Name; } block = this.resources.Resources.FirstOrDefault(x => x is lsctResource); if (block != null) { var lyvr = (lsctResource)block; this.sectionType = lyvr.SectionType; } //if (this.resources.Resources.Contains("SoLd.Idnt") == true) // this.placedID = this.resources.Resources.ToGuid("SoLd.Idnt"); // else if (this.resources.Resources.Contains("SoLE.Idnt") == true) // this.placedID = this.resources.Resources.ToGuid("SoLE.Idnt"); placedID = Guid.Empty; }
public static void GetBlocks(IResourceBlock rootBlock, out IList <IResourceBlock> sys, out IList <IResourceBlock> gfx) { var systemBlocks = new HashSet <IResourceBlock>(); var graphicBlocks = new HashSet <IResourceBlock>(); var processed = new HashSet <IResourceBlock>(); void addBlock(IResourceBlock block) { if (block is IResourceSystemBlock) { systemBlocks.Add(block); } else if (block is IResourceGraphicsBlock) { graphicBlocks.Add(block); } } void addChildren(IResourceBlock block) { if (block is IResourceSystemBlock sblock) { var references = sblock.GetReferences(); foreach (var reference in references) { if (processed.Add(reference)) { addBlock(reference); addChildren(reference); } } var parts = sblock.GetParts(); foreach (var part in parts) { addChildren(part.Item2); } } } addBlock(rootBlock); addChildren(rootBlock); sys = new List <IResourceBlock>(systemBlocks); gfx = new List <IResourceBlock>(graphicBlocks); }
private void CopyIndexedResource(Stream outputStream, IResourceBlock resourceBlock, int resourceCount) { for (var i = 0; i < resourceCount; i++) { var address = resourceBlock.GetResourcePointer(i); var length = resourceBlock.GetResourceLength(i); switch (address.Source) { case Halo2.ResourceSource.Local: CopyLocalResource(outputStream, resourceBlock, address, length, i); break; default: // we don't need to do anything with external resources continue; } } }
private void CopyLocalResource(Stream outputStream, IResourceBlock resourceBlock, ResourcePointer address, int length, int index = 0) { // the resource has already been copied if (address < GetFilePosition( )) { // if this is true then we've already handled this resource so use the // new address ResourcePointer newAddress; if (ShiftData.TryGetValue(address, out newAddress)) { resourceBlock.SetResourcePointer(newAddress, index); return; } // has the resource already been copied? Has it been moved? // well, shit. System.Diagnostics.Debug.WriteLineIf(address < GetFilePosition( ), "Warning: address < GetFilePosition()"); this.Seek(address); } // this is not strictly an error but it should be treated as such if (address > GetFilePosition( )) { System.Diagnostics.Debug.WriteLineIf(address > GetFilePosition( ), "Warning: address > GetFilePosition()"); this.Seek(address); } System.Diagnostics.Debug.WriteLineIf(address % 512 != 0, "Warning: address % 512 != 0"); if (outputStream.Position % 512 != 0) { System.Diagnostics.Debug.WriteLineIf(outputStream.Position % 512 != 0, "Warning: output address % 512 != 0"); } var position = outputStream.Position; ShiftData[address] = ( int )position; resourceBlock.SetResourcePointer(( int )position, index); var size = Padding.Align(length, 512); this.BufferedCopyBytesTo(size, outputStream); }
public ResourceBuilderBlockSet(IList <IResourceBlock> blocks, bool hasRootBlock) { if (blocks.Count < 1) { return; } int indexStart = 0; _count = blocks.Count; if (hasRootBlock) { RootBlock = blocks[0]; indexStart = 1; _count--; } buckets = new Dictionary <long, LinkedList <IResourceBlock> >(); for (int i = indexStart; i < blocks.Count; i++) { var block = blocks[i]; long bucketKey = block.BlockLength; if (buckets.TryGetValue(bucketKey, out LinkedList <IResourceBlock> bucketValue)) { bucketValue.AddLast(block); } else { var linkedList = new LinkedList <IResourceBlock>(); linkedList.AddLast(block); buckets[bucketKey] = linkedList; } } _orderedKeys = buckets.Keys.ToList(); _orderedKeys.Sort((a, b) => b.CompareTo(a)); }
public static byte[] GetResourceData(this IResourceBlock resourceInfoBlock, int index = 0) { return(resourceInfoBlock.GetResourceFromCache(index)); }
/// <summary> /// Writes a block. /// </summary> public void WriteBlock(IResourceBlock value) { value.Write(this); }
public ResourceBuilderBlock(IResourceBlock block) { Block = block; Length = block?.BlockLength ?? 0; }
//private static void GetPagesFromFlags( // int flags, // out int pagesDiv16, // out int pagesDiv8, // out int pagesDiv4, // out int pagesDiv2, // out int pagesMul1, // out int pagesMul2, // out int pagesMul4, // out int pagesMul8, // out int pagesMul16, // out int pagesSizeShift) //{ // pagesDiv16 = (int)(flags >> 27) & 0x1; // pagesDiv8 = (int)(flags >> 26) & 0x1; // pagesDiv4 = (int)(flags >> 25) & 0x1; // pagesDiv2 = (int)(flags >> 24) & 0x1; // pagesMul1 = (int)(flags >> 17) & 0x7F; // pagesMul2 = (int)(flags >> 11) & 0x3F; // pagesMul4 = (int)(flags >> 7) & 0xF; // pagesMul8 = (int)(flags >> 5) & 0x3; // pagesMul16 = (int)(flags >> 4) & 0x1; // pagesSizeShift = (int)(flags >> 0) & 0xF; //} //private static int GetFlagsFromPages( // int pagesDiv16, // int pagesDiv8, // int pagesDiv4, // int pagesDiv2, // int pagesMul1, // int pagesMul2, // int pagesMul4, // int pagesMul8, // int pagesMul16, // int pagesSizeShift) //{ // if (pagesDiv16 < 0 || pagesDiv16 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv8 < 0 || pagesDiv8 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv4 < 0 || pagesDiv4 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv2 < 0 || pagesDiv2 > 1) throw new Exception("Illegal number of pages."); // if (pagesMul1 < 0 || pagesMul1 > 127) throw new Exception("Illegal number of pages."); // if (pagesMul2 < 0 || pagesMul2 > 63) throw new Exception("Illegal number of pages."); // if (pagesMul4 < 0 || pagesMul4 > 15) throw new Exception("Illegal number of pages."); // if (pagesMul8 < 0 || pagesMul8 > 3) throw new Exception("Illegal number of pages."); // if (pagesMul16 < 0 || pagesMul16 > 1) throw new Exception("Illegal number of pages."); // int flags = 0; // flags |= pagesDiv16 << 27; // flags |= pagesDiv8 << 26; // flags |= pagesDiv4 << 25; // flags |= pagesDiv2 << 24; // flags |= pagesMul1 << 17; // flags |= pagesMul2 << 11; // flags |= pagesMul4 << 7; // flags |= pagesMul8 << 5; // flags |= pagesMul16 << 4; // flags |= pagesSizeShift; // return flags; //} public static void GetBlocks(IResourceBlock rootBlock, out IList <IResourceBlock> sys, out IList <IResourceBlock> gfx) { var systemBlocks = new HashSet <IResourceBlock>(); var graphicBlocks = new HashSet <IResourceBlock>(); var protectedBlocks = new List <IResourceBlock>(); var stack = new Stack <IResourceBlock>(); stack.Push(rootBlock); var processed = new HashSet <IResourceBlock>(); processed.Add(rootBlock); while (stack.Count > 0) { var block = stack.Pop(); if (block == null) { continue; } if (block is IResourceSystemBlock) { if (!systemBlocks.Contains(block)) { systemBlocks.Add(block); } // for system blocks, also process references... var references = ((IResourceSystemBlock)block).GetReferences(); //Array.Reverse(references); foreach (var reference in references) { if (!processed.Contains(reference)) { stack.Push(reference); processed.Add(reference); } } var subs = new Stack <IResourceSystemBlock>(); foreach (var part in ((IResourceSystemBlock)block).GetParts()) { subs.Push((IResourceSystemBlock)part.Item2); } while (subs.Count > 0) { var sub = subs.Pop(); foreach (var x in sub.GetReferences()) { if (!processed.Contains(x)) { stack.Push(x); processed.Add(x); } } foreach (var x in sub.GetParts()) { subs.Push((IResourceSystemBlock)x.Item2); } protectedBlocks.Add(sub); } } else { if (!graphicBlocks.Contains(block)) { graphicBlocks.Add(block); } } } //var result = new List<IResourceBlock>(); //result.AddRange(systemBlocks); //result.AddRange(graphicBlocks); //return result; // there are now sys-blocks in the list that actually // only substructures and therefore must not get // a new position! // -> remove them from the list foreach (var q in protectedBlocks) { if (systemBlocks.Contains(q)) { systemBlocks.Remove(q); } } sys = new List <IResourceBlock>(); foreach (var s in systemBlocks) { sys.Add(s); } gfx = new List <IResourceBlock>(); foreach (var s in graphicBlocks) { gfx.Add(s); } }
public void SetExtraRecords(LayerMaskBlock layerMask, LayerBlendingRangesBlock blendingRanges, IResourceBlock[] resources, string name) { this.layerMask = layerMask; this.blendingRanges = blendingRanges; this.resources = resources; this.name = name; IResourceBlock block = null; block = this.Resources.FirstOrDefault(x => x is luniResource); if (block != null) { var luni = (luniResource)block; this.name = luni.Name; } block = this.Resources.FirstOrDefault(x => x is lyvrResource); if (block != null) { var lyvr = (lyvrResource)block; this.version = lyvr.Version; } block = this.Resources.FirstOrDefault(x => x is lsctResource); if (block != null) { var lyvr = (lsctResource)block; this.sectionType = lyvr.SectionType; } else { block = this.Resources.FirstOrDefault(x => x is lsdkResource); if (block != null) { var lyvr = (lsdkResource)block; this.sectionType = lyvr.SectionType; } } //if (this.resources.Contains("SoLd.Idnt") == true) // this.placedID = this.resources.ToGuid("SoLd.Idnt"); // else if (this.resources.Contains("SoLE.Idnt") == true) // this.placedID = this.resources.ToGuid("SoLE.Idnt"); placedID = Guid.Empty; foreach (var item in this.channels) { switch (item.Type) { case ChannelType.Mask: { if (this.layerMask != null) { item.Width = this.layerMask.Width; item.Height = this.layerMask.Height; } } break; case ChannelType.Alpha: { var iOpablock = this.Resources.FirstOrDefault(x => x is iOpaResource) as iOpaResource; if (iOpablock != null) { var iOpa = (iOpaResource)block; byte opa = iOpa.Opacity; item.Opacity = opa / 255.0f; } } break; } } }
private void CopyResource(Stream outputStream, IResourceBlock resourceBlock) { CopyIndexedResource(outputStream, resourceBlock, 1); }
//private static void GetPagesFromFlags( // int flags, // out int pagesDiv16, // out int pagesDiv8, // out int pagesDiv4, // out int pagesDiv2, // out int pagesMul1, // out int pagesMul2, // out int pagesMul4, // out int pagesMul8, // out int pagesMul16, // out int pagesSizeShift) //{ // pagesDiv16 = (int)(flags >> 27) & 0x1; // pagesDiv8 = (int)(flags >> 26) & 0x1; // pagesDiv4 = (int)(flags >> 25) & 0x1; // pagesDiv2 = (int)(flags >> 24) & 0x1; // pagesMul1 = (int)(flags >> 17) & 0x7F; // pagesMul2 = (int)(flags >> 11) & 0x3F; // pagesMul4 = (int)(flags >> 7) & 0xF; // pagesMul8 = (int)(flags >> 5) & 0x3; // pagesMul16 = (int)(flags >> 4) & 0x1; // pagesSizeShift = (int)(flags >> 0) & 0xF; //} //private static int GetFlagsFromPages( // int pagesDiv16, // int pagesDiv8, // int pagesDiv4, // int pagesDiv2, // int pagesMul1, // int pagesMul2, // int pagesMul4, // int pagesMul8, // int pagesMul16, // int pagesSizeShift) //{ // if (pagesDiv16 < 0 || pagesDiv16 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv8 < 0 || pagesDiv8 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv4 < 0 || pagesDiv4 > 1) throw new Exception("Illegal number of pages."); // if (pagesDiv2 < 0 || pagesDiv2 > 1) throw new Exception("Illegal number of pages."); // if (pagesMul1 < 0 || pagesMul1 > 127) throw new Exception("Illegal number of pages."); // if (pagesMul2 < 0 || pagesMul2 > 63) throw new Exception("Illegal number of pages."); // if (pagesMul4 < 0 || pagesMul4 > 15) throw new Exception("Illegal number of pages."); // if (pagesMul8 < 0 || pagesMul8 > 3) throw new Exception("Illegal number of pages."); // if (pagesMul16 < 0 || pagesMul16 > 1) throw new Exception("Illegal number of pages."); // int flags = 0; // flags |= pagesDiv16 << 27; // flags |= pagesDiv8 << 26; // flags |= pagesDiv4 << 25; // flags |= pagesDiv2 << 24; // flags |= pagesMul1 << 17; // flags |= pagesMul2 << 11; // flags |= pagesMul4 << 7; // flags |= pagesMul8 << 5; // flags |= pagesMul16 << 4; // flags |= pagesSizeShift; // return flags; //} public static void GetBlocks(IResourceBlock rootBlock, out IList<IResourceBlock> sys, out IList<IResourceBlock> gfx) { var systemBlocks = new HashSet<IResourceBlock>(); var graphicBlocks = new HashSet<IResourceBlock>(); var protectedBlocks = new List<IResourceBlock>(); var stack = new Stack<IResourceBlock>(); stack.Push(rootBlock); var processed = new HashSet<IResourceBlock>(); processed.Add(rootBlock); while (stack.Count > 0) { var block = stack.Pop(); if (block == null) continue; if (block is IResourceSystemBlock) { if (!systemBlocks.Contains(block)) systemBlocks.Add(block); // for system blocks, also process references... var references = ((IResourceSystemBlock)block).GetReferences(); //Array.Reverse(references); foreach (var reference in references) if (!processed.Contains(reference)) { stack.Push(reference); processed.Add(reference); } var subs = new Stack<IResourceSystemBlock>(); foreach (var part in ((IResourceSystemBlock)block).GetParts()) subs.Push((IResourceSystemBlock)part.Item2); while (subs.Count > 0) { var sub = subs.Pop(); foreach (var x in sub.GetReferences()) if (!processed.Contains(x)) { stack.Push(x); processed.Add(x); } foreach (var x in sub.GetParts()) subs.Push((IResourceSystemBlock)x.Item2); protectedBlocks.Add(sub); } } else { if (!graphicBlocks.Contains(block)) graphicBlocks.Add(block); } } //var result = new List<IResourceBlock>(); //result.AddRange(systemBlocks); //result.AddRange(graphicBlocks); //return result; // there are now sys-blocks in the list that actually // only substructures and therefore must not get // a new position! // -> remove them from the list foreach (var q in protectedBlocks) if (systemBlocks.Contains(q)) systemBlocks.Remove(q); sys = new List<IResourceBlock>(); foreach (var s in systemBlocks) sys.Add(s); gfx = new List<IResourceBlock>(); foreach (var s in graphicBlocks) gfx.Add(s); }