private static Scroll FindMatchingScroll(List <ScrollObject> scrolls, int vertexSegmentedAddress, TextureDescription td) { foreach (ScrollObject scroll in scrolls) { if (scroll is EditorScroll editorScroll) { if (editorScroll.segmentedAddress <= vertexSegmentedAddress && vertexSegmentedAddress < editorScroll.segmentedAddress + editorScroll.vertexCount * 0x10) { return(scroll); } } if (scroll is TextureScroll textureScroll) { if (td.f2SegmentedAddress == textureScroll.segmentedAddress) { return(scroll); } } } return(null); }
public static void GetTriangleMap(ROM realRom, Region region, int maxDLLength, List <ScrollObject> scrolls, out TriangleMap map, out SortedRegionList vertexData) { TriangleMapParseState state = new TriangleMapParseState(scrolls); DisplayListRegion dlRegion = (DisplayListRegion)region; map = new TriangleMap(); realRom.PushOffset(region.romStart); byte curCmdIndex; do { curCmdIndex = realRom.Read8(); TriangleMapParserCmd func = triangleMapParser[curCmdIndex]; func(realRom, map, state); realRom.AddOffset(8); }while (realRom.offset < region.romStart + region.length); realRom.PopOffset(); // Check map validity // There are 2 possible ways to mess up scroll // 'Too much' - scroll is performing too much scrolling, 1st warn detect, 2nd falsing, 3rd can fix such scroll if scrolls are done properly // 'Not enough' - scroll is not scrolling the whole texture, 2nd warn may be able to detect that, no fix yet but 'stretch' the scroll should work // I assume there is no scrolls that do not correspond to no texture, such case will leave weird things :) // Currently ScrollingTextures cannot be longed so it is impossible to fix 'Not enough' :( List <ScrollingTextureDescription> brokenTextures = new List <ScrollingTextureDescription>(); { // Not enough HashSet <TextureDescription> scrollingTds = new HashSet <TextureDescription>(map.map.Keys.Where(k => k.scroll != null)); foreach (TextureDescription td in scrollingTds) { var stds = map.map.Keys.Where(k => k.Equals(td)).ToList(); if (stds.Count() > 1) { int a = 0; } } // Check if scroll 'fits' foreach (ScrollingTextureDescription std in map.map.Keys) { if (std.scroll == null) { continue; } if (!std.vertexRegions.Equals(std.scrollRegions)) { brokenTextures.Add(std); } } } foreach (ScrollingTextureDescription brokenTd in brokenTextures) { if (brokenTd.omitScrollCheck) { continue; } // Figure out the way to "heal", either drop scroll or extend it // If scroll does not start at the same place, just drop it, such solution may backfire if 2 scrolls intersect bool shouldDrop = brokenTd.scrollRegions.RegionList.First().Key != brokenTd.vertexRegions.RegionList.First().Key; if (shouldDrop) { // Find if texture without scroll exists, if it does, merge tris in it, otherwise drop the scroll List <ScrollingTextureDescription> similarTextures = map.map.Keys.Where(k => k.scroll == null).Where(k => TextureDescription.Equals(brokenTd, k)).ToList(); if (similarTextures.Count() != 0) { ScrollingTextureDescription stdNoScroll = similarTextures[0]; List <Triangle> tris = map.map[brokenTd]; map.map.Remove(brokenTd); map.map[stdNoScroll].AddRange(tris); } else { state.td.scroll = null; } } else { // Find if texture without scroll exists, if it does, merge tris from it (make it scroll) List <ScrollingTextureDescription> similarTextures = map.map.Keys.Where(k => k.scroll == null).Where(k => TextureDescription.Equals(brokenTd, k)).ToList(); foreach (ScrollingTextureDescription similarStd in similarTextures) { List <Triangle> tris = map.map[similarStd]; map.map.Remove(similarStd); map.map[brokenTd].AddRange(tris); } } } vertexData = state.vertexBytes; }
public override bool Equals(object obj) { TextureDescription list = (TextureDescription)(obj); return(Enumerable.SequenceEqual(cmds, list.cmds)); }
static public bool Equals(TextureDescription td1, TextureDescription td2) { return(Enumerable.SequenceEqual(td1.cmds, td2.cmds)); }
public void AddRange(TextureDescription other) { cmds.AddRange(other.cmds); f2SegmentedAddress = other.f2SegmentedAddress; }