private static void TriangleMapParse_cmd04(ROM rom, TriangleMap map, TriangleMapParseState state) { state.vertexLoadCmd = (UInt64)rom.Read64(); byte vertexDesc = rom.Read8(1); byte vertexCount = (byte)(((vertexDesc & 0xF0) >> 4) + 1); byte vertexOffset = (byte)((vertexDesc & 0x0F)); Int32 vertexSegmentedAddress = rom.Read32(4); state.segmentedVertexBufferAddress = vertexSegmentedAddress; Int32 romPtr = rom.GetROMAddress(vertexSegmentedAddress); if (romPtr == -1) { throw new ArgumentException("Invalid segmented address!"); } rom.PushOffset(romPtr); for (int vertex = vertexOffset; vertex < vertexCount; vertex++) { Int64 lo = rom.Read64(); Int64 hi = rom.Read64(8); state.vbuf[vertex] = new Vertex((UInt64)lo, (UInt64)hi); state.vbufRomStart[vertex] = rom.offset; state.scrollBuf[vertex] = FindMatchingScroll(state.scrolls, vertexSegmentedAddress, state.td); rom.AddOffset(0x10); vertexSegmentedAddress += 0x10; } rom.PopOffset(); }
private static void FixParse_cmdB9(ROM rom, DisplayListRegion region, RegionFixState state) { if (state.config.disableFog) { rom.Write64(0); return; } if (!state.config.fixOtherMode) { return; } if (!region.isFogEnabled) { return; } if ((ulong)rom.Read64(-8) != 0xBA00140200000000 || (ulong)rom.Read64(8) != 0xB600000000010000) { return; } UInt64 B9Cmd = OtherMode.GetB9Cmd(region.layer); if (B9Cmd != 0) { rom.Write64(B9Cmd); } }
private static void OptimizeParse_cmd04(ROM rom, DisplayListRegion region, RegionOptimizeState state) { // initial state if (state.last04Cmd == 0) { state.last04Cmd = rom.Read64(); return; } Int64 cmd = rom.Read64(); // if current 04 loads the same vertices, remove current cmd if (cmd == state.last04Cmd) { rom.Write64(0); return; } // new vertices are being loaded, update the thing state.last04Cmd = cmd; // if previous cmd is 0x04, it will be overriden by current 04 anyways if (rom.Read8(-8) == 0x04) { rom.Write64(0, -8); } }
private static void RelocationParse_cmdB9(ROM rom, RelocationTable table, DisplayListRegion region) { if (!region.DLFixesNeeded) { return; } if (!region.isFogEnabled) { return; } if ((ulong)rom.Read64(-8) != 0xBA00140200000000) { return; } if (region.layer == 1) { rom.Write64(0xB900031D00552078); } if (region.layer == 4) { rom.Write64(0xB900031D00443078); } if (region.layer == 5) { rom.Write64(0xB900031D005049D8); } }
private static void RegionParse_cmdB9(ROM rom, List <Region> regions, RegionParseState state) { if (state.B9cmdfirst == 0) { state.B9cmdfirst = rom.Read64(); } }
private static void OptimizeParse_cmdB7(ROM rom, DisplayListRegion region, RegionOptimizeState state) { // Very failsafe approach state.lastB6Cmd = 0; Int64 cmd = rom.Read64(); // Basically NOP if ((UInt64)cmd == 0xB700000000000000) { rom.Write64(0); return; } // initial state if (state.lastB7Cmd == 0) { state.lastB7Cmd = cmd; return; } // if current cmd loads the same, remove current cmd if (cmd == state.lastB7Cmd) { rom.Write64(0); return; } }
private static void RegionParse_cmdFC(ROM rom, List <Region> regions, RegionParseState state) { if (state.FCcmd == -1) { state.FCcmd = rom.Read64(); } state.FCCount++; }
private static void TriangleMapParse_common(ROM rom, TriangleMap map, TriangleMapParseState state) { switch (state.state) { case VisualMapParseStateCmd.Header: map.AddHeaderCmd((UInt64)rom.Read64()); break; case VisualMapParseStateCmd.Texture: state.td.Add((UInt64)rom.Read64(), rom.GetSegmentedAddress(rom.offset)); break; case VisualMapParseStateCmd.Footer: map.AddFooterCmd((UInt64)rom.Read64()); break; } }
private static void TriangleMapParse_cmdBB(ROM rom, TriangleMap map, TriangleMapParseState state) { if ((UInt64)rom.Read64() == 0xBB000000FFFFFFFF) { state.state = VisualMapParseStateCmd.Footer; } TriangleMapParse_common(rom, map, state); }
public static void PerformVisualMapRebuild(ROM realRom, Region region, int maxDLLength) { // This is fake rom but it works anyways, just more convenient // Want to be safe with overwriting the whole display list ROM fakeRom = new ROM(region.data); VisualMapParseState state = new VisualMapParseState(); DisplayListRegion dlRegion = (DisplayListRegion)region; VisualMap map = new VisualMap(); byte curCmdIndex; do { curCmdIndex = fakeRom.Read8(); VisualMapParserCmd func = visualMapParser[curCmdIndex]; func(fakeRom, map, state); fakeRom.AddOffset(8); }while (fakeRom.offset < region.length); ROM visualMapROM = new ROM(new byte[maxDLLength]); int visualMapLength = map.MakeF3D(visualMapROM); // Now write data to real rom + trimming // bzero fakeRom.offset = 0; realRom.PushOffset(region.romStart); { do { realRom.Write64(0x0101010101010101); realRom.AddOffset(8); fakeRom.AddOffset(8); } while (fakeRom.offset < region.length); } realRom.PopOffset(); visualMapROM.offset = 0; realRom.PushOffset(region.romStart); { int start = region.romStart; do { Int64 cmd = visualMapROM.Read64(); visualMapROM.AddOffset(8); realRom.Write64((ulong)cmd); realRom.AddOffset(8); } while (visualMapROM.offset < visualMapLength); region.length = realRom.offset - start; region.data = new byte[region.length]; realRom.ReadData(region.romStart, region.length, region.data); } realRom.PopOffset(); }
public static void PerformRegionOptimize(ROM realRom, Region region, FixConfig config) { // This is fake rom but it works anyways, just more convenient // Want to be safe with overwriting the whole display list ROM fakeRom = new ROM(region.data); RegionOptimizeState state = new RegionOptimizeState(config); DisplayListRegion dlRegion = (DisplayListRegion)region; byte curCmdIndex; do { curCmdIndex = fakeRom.Read8(); OptimizeParserCmd func = optimizeParser[curCmdIndex]; func(fakeRom, dlRegion, state); fakeRom.AddOffset(8); }while (fakeRom.offset < region.length); // Now write data to real rom + trimming // bzero fakeRom.offset = 0; realRom.PushOffset(region.romStart); { do { realRom.Write64(0x0101010101010101); realRom.AddOffset(8); fakeRom.AddOffset(8); } while (fakeRom.offset < region.length); } realRom.PopOffset(); fakeRom.offset = 0; realRom.PushOffset(region.romStart); { int start = region.romStart; do { Int64 cmd = fakeRom.Read64(); fakeRom.AddOffset(8); if (config.trimNOPs && cmd == 0 && dlRegion.isUnusedTrimmingAllowed) { continue; } realRom.Write64((ulong)cmd); realRom.AddOffset(8); } while (fakeRom.offset < region.length); region.length = realRom.offset - start; region.data = new byte[region.length]; realRom.ReadData(region.romStart, region.length, region.data); } realRom.PopOffset(); }
private static void VisualMapParse_cmdFB(ROM rom, VisualMap map, VisualMapParseState state) { // Some importers have the only EnvColor func for everything lmfao if (rom.Read8(8) != 0xFD) { goto fini; } state.envColorCmd = (ulong)rom.Read64(); state.state = VisualMapParseStateCmd.Texture; state.td = new TextureDescription(); fini: VisualMapParse_common(rom, map, state); }
private static void OptimizeParse_cmdBC(ROM rom, DisplayListRegion region, RegionOptimizeState state) { Int64 cmd = rom.Read64(); // initial state if (state.lastBCCmd == 0) { state.lastBCCmd = cmd; return; } // if current cmd loads the same, remove current cmd if (cmd == state.lastBCCmd) { rom.Write64(0); return; } }
private static void RegionParse_cmd10(ROM rom, List <Region> regions, RegionParseState state) { if (rom.Read64() == 0x1008000000000000) { if (rom.offset == state.start) { state.start = rom.offset + rom.Read8(1); } // Skip empty commands in the beginning of any region else if (rom.offset == state.start + rom.Read8(1)) { state.start = rom.offset + rom.Read8(1); } else { // Commands is not in the beginning, cut area, start new one that is same as it was before if (state.regionState == RegionState.ModelsLoader) { CutRegion(rom, regions, state, rom.offset, state.regionState); } } } }
private static void VisualMapParse_cmdBF(ROM rom, VisualMap map, VisualMapParseState state) { state.isHeader = false; state.state = VisualMapParseStateCmd.Footer; map.AddTriangle(state.td, state.vertexLoadCmd, (UInt64)rom.Read64()); }
private static void VisualMapParse_cmd04(ROM rom, VisualMap map, VisualMapParseState state) { state.vertexLoadCmd = (UInt64)rom.Read64(); }