public override bool Equals(object obj) { ScrollingTextureDescription std = (ScrollingTextureDescription)obj; if (scroll != null && !scroll.Equals(std.scroll)) { return(false); } return(base.Equals(obj)); }
public TriangleMapParseState(List <ScrollObject> scrolls) { state = VisualMapParseStateCmd.Header; td = new ScrollingTextureDescription(); isHeader = true; segmentedVertexBufferAddress = -1; vbuf = new Vertex[16]; scrollBuf = new Scroll[16]; vbufRomStart = new Int32[16]; this.scrolls = scrolls; vertexBytes = new SortedRegionList(); }
private static void TriangleMapParse_cmdBF(ROM rom, TriangleMap map, TriangleMapParseState state) { state.isHeader = false; state.state = VisualMapParseStateCmd.Footer; byte v0index = (byte)(rom.Read8(5) / 0xA); byte v1index = (byte)(rom.Read8(6) / 0xA); byte v2index = (byte)(rom.Read8(7) / 0xA); state.vertexBytes.AddRegion(state.vbufRomStart[v0index], 0x10); state.vertexBytes.AddRegion(state.vbufRomStart[v1index], 0x10); state.vertexBytes.AddRegion(state.vbufRomStart[v2index], 0x10); // This assumes all scrolls are scrolling at the same speed which is usually true :3 if (state.scrollBuf[v0index] != state.scrollBuf[v1index] || state.scrollBuf[v0index] != state.scrollBuf[v2index] || state.scrollBuf[v1index] != state.scrollBuf[v2index]) { throw new Exception("Vertices are scrolling at different scrolls"); } Scroll scroll = state.scrollBuf[v0index]; if ((scroll == null && state.td.scroll != null) || (scroll != null && !scroll.Equals(state.td.scroll))) { ScrollingTextureDescription oldTd = state.td; state.td = new ScrollingTextureDescription(); state.td.AddRange(oldTd); state.td.scroll = scroll; if (scroll is EditorScroll editorScroll) { state.td.RegisterScroll(editorScroll); } if (scroll is TextureScroll) { state.td.omitScrollCheck = true; } } state.td.RegisterVertex(state.segmentedVertexBufferAddress + v0index * 0x10); state.td.RegisterVertex(state.segmentedVertexBufferAddress + v1index * 0x10); state.td.RegisterVertex(state.segmentedVertexBufferAddress + v2index * 0x10); map.AddTriangle(state.td, state.vbuf[v0index], state.vbuf[v1index], state.vbuf[v2index]); }
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; }