public RegionParseState() { textureData = new SortedRegionList(); vertexData = new SortedRegionList(); lightData = new SortedRegionList(); FDAddress = -1; retAddressStack = new Stack <int>(); }
public RegionParseState() { textureData = new SortedRegionList(); vertexData = new SortedRegionList(); lightData = new SortedRegionList(); FDAddress = -1; FCcmd = -1; isUnusedTrimmingAllowed = true; retAddressStack = new Stack <int>(); }
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(); }
static RegionParseState PerformRegionParseInternal(ROM rom, List <Region> regions, int offset, int layer) { RegionParseState state = new RegionParseState(); rom.PushOffset(offset); try { int cmd = 0; do { cmd = rom.Read8(); parser[cmd](rom, regions, state); rom.AddOffset(8); }while (cmd != 0xB8); Region region; SortedRegionList graphicsData = new SortedRegionList(); foreach (KeyValuePair <int, int> lightRegion in state.lightData.RegionList) { //region = new Region(lightRegion.Key, lightRegion.Value, RegionState.LightData); graphicsData.AddRegion(lightRegion.Key, lightRegion.Value); //regions.Add(region); } // kostul if (state.lightData.RegionList.Count == 0) { graphicsData.AddRegion(rom.GetROMAddress(0x0E000000), 0x10); } foreach (KeyValuePair <int, int> textureRegion in state.textureData.RegionList) { //region = new Region(textureRegion.Key, textureRegion.Value, RegionState.TextureInfo); graphicsData.AddRegion(textureRegion.Key, textureRegion.Value); //regions.Add(region); } foreach (KeyValuePair <int, int> vertexRegion in state.vertexData.RegionList) { //region = new Region(vertexRegion.Key, vertexRegion.Value, RegionState.VertexInfo); graphicsData.AddRegion(vertexRegion.Key, vertexRegion.Value); //regions.Add(region); } int count = 0; foreach (KeyValuePair <int, int> notFixedRegion in graphicsData.RegionList) { region = new DynamicRegion(notFixedRegion.Key, notFixedRegion.Value, RegionState.GraphicsData); region.number = count++; regions.Add(region); } region = new DisplayListRegion(offset, rom.offset - offset, state.isFogEnabled, state.isEnvColorEnabled, state.FCCount, state.B9cmdfirst, layer); regions.Add(region); } finally { rom.PopOffset(); } return(state); }
public static void RebuildTriangleMap(ROM realRom, Region region, int maxDLLength, TriangleMap map, SortedRegionList vertexData, ScrollFactory factory) { ROM fakeRom = (ROM)realRom.Clone(); // bzero fakeRom.PushOffset(region.romStart); { do { fakeRom.Write64(0x0101010101010101); fakeRom.AddOffset(8); } while (fakeRom.offset < region.romStart + region.length); } fakeRom.PopOffset(); fakeRom.offset = region.romStart; int triangleMapLength = map.MakeF3D(fakeRom, vertexData, factory); if (triangleMapLength > maxDLLength) { throw new OutOfMemoryException("No memory for DL available :("); } realRom.TransferFrom(fakeRom); realRom.offset = fakeRom.offset; region.length = realRom.offset - region.romStart; region.data = new byte[region.length]; realRom.ReadData(region.romStart, region.length, region.data); }
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; }
private void button1_Click(object sender, EventArgs e) { GC.Collect(); foreach (DataGridViewRow row in dataGridView1.Rows) { rom.segments = (SegmentDescriptor[])row.Cells[8].Value; List <ScrollObject> scrolls = (List <ScrollObject>)row.Cells[9].Value; DisplayListRegion dlRegion = (DisplayListRegion)row.Cells[0].Value; Boolean fixingCheckBox = (Boolean)row.Cells[1].Value; DisplayList.FixConfig config = new DisplayList.FixConfig(checkBoxNerfFog.Checked, checkBoxOptimizeVertex.Checked, checkBoxTrimNops.Checked, checkBoxCombiners.Checked, checkBoxOtherMode.Checked, checkBoxNoFog.Checked); if (fixingCheckBox) { if (checkBoxNoFog.Checked) { dlRegion.isFogEnabled = false; } int maxDlLength = dlRegion.length; DisplayList.PerformRegionFix(rom, dlRegion, config); if (checkBoxOptimizeVertex.Checked) { DisplayList.PerformRegionOptimize(rom, dlRegion, config); } try { if (checkBoxGroupByTexture.Checked && !checkBoxRebuildVertices.Checked) { DisplayList.PerformVisualMapRebuild(rom, dlRegion, maxDlLength); } //DisplayList.PerformRegionOptimize(rom, dlRegion, config); } catch (Exception) { } } } if (checkBoxGroupByTexture.Checked && checkBoxRebuildVertices.Checked) { Dictionary <int, List <DataGridViewRow> > levelDatas = new Dictionary <int, List <DataGridViewRow> >(); foreach (DataGridViewRow row in dataGridView1.Rows) { Boolean fixingCheckBox = (Boolean)row.Cells[1].Value; if (!fixingCheckBox) { continue; } int level = (int)row.Cells[3].Value; if (!levelDatas.Keys.Contains(level)) { levelDatas[level] = new List <DataGridViewRow>(); } levelDatas[level].Add(row); } foreach (int level in levelDatas.Keys) { ROM romCopy = (ROM)rom.Clone(); try { List <DataGridViewRow> rows = levelDatas[level]; rom.segments = (SegmentDescriptor[])rows[0].Cells[8].Value; List <ScrollObject> scrolls = (List <ScrollObject>)rows[0].Cells[9].Value; foreach (ScrollObject scr in scrolls) { scr.Disable(rom); } ScrollFactory factory = new ScrollFactory(scrolls); SortedRegionList vertexData = new SortedRegionList(); List <KeyValuePair <DataGridViewRow, TriangleMap> > rowMaps = new List <KeyValuePair <DataGridViewRow, TriangleMap> >(); foreach (DataGridViewRow row in rows) { DisplayListRegion dlRegion = (DisplayListRegion)row.Cells[0].Value; int maxDlLength = dlRegion.length; DisplayList.GetTriangleMap(rom, dlRegion, maxDlLength, scrolls, out TriangleMap map, out SortedRegionList levelVertexData); rowMaps.Add(new KeyValuePair <DataGridViewRow, TriangleMap>(row, map)); vertexData.AddRegions(levelVertexData); } foreach (KeyValuePair <DataGridViewRow, TriangleMap> kvp in rowMaps) { DataGridViewRow row = kvp.Key; TriangleMap map = kvp.Value; DisplayListRegion dlRegion = (DisplayListRegion)row.Cells[0].Value; int maxDlLength = dlRegion.length; DisplayList.RebuildTriangleMap(rom, dlRegion, maxDlLength, map, vertexData, factory); } } catch (Exception) { rom = romCopy; } } } File.WriteAllBytes(path, rom.rom); MessageBox.Show(String.Format("ROM was patched successfully"), "f3d fix", MessageBoxButtons.OK, MessageBoxIcon.Information); }
public ScrollingTextureDescription() : base() { scrollRegions = new SortedRegionList(); vertexRegions = new SortedRegionList(); omitScrollCheck = false; }