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 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 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); } }
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(); }
public void MakeF3D(ROM rom) { foreach (UInt64 cmd04 in data.Keys) { rom.Write64(cmd04); rom.AddOffset(8); SortedSet <UInt64> set = data[cmd04]; foreach (UInt64 cmdBF in set) { rom.Write64(cmdBF); rom.AddOffset(8); } } }
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); }
private static void FixParse_cmdF8(ROM rom, DisplayListRegion region, RegionFixState state) { if (state.config.disableFog) { rom.Write64(0); } }
private static void FixParse_cmdBC(ROM rom, DisplayListRegion region, RegionFixState state) { if (state.config.disableFog) { rom.Write64(0); return; } if (state.config.nerfFog) { float A = rom.Read16(4); float B = rom.Read16(6); float min = 500 * (1 - B / A); float max = 128000 / A + min; // nerf fog min += 5; A = 128000 / (max - min); B = (500 - min) * 256 / (max - min); int Aint = (int)A; int Bint = (int)B; rom.Write16(Aint, 4); rom.Write16(Bint, 6); } }
private static void OptimizeParse_cmdFD(ROM rom, DisplayListRegion region, RegionOptimizeState state) { if (state.prevFDcmdAddr != 0) { rom.PushOffset(state.prevFDcmdAddr); rom.Write64(0); rom.PopOffset(); } state.prevFDcmdAddr = rom.offset; }
public void MakeF3D(ROM rom) { foreach (UInt64 cmd in cmds) { rom.Write64(cmd); if ((cmd & 0xF200000000000000) == 0xF200000000000000) { f2SegmentedAddress = rom.GetSegmentedAddress(rom.offset); } rom.AddOffset(8); } }
public static void PerformTriangleMapRebuild(ROM realRom, Region region, int maxDLLength, List <ScrollObject> scrolls) { TriangleMapParseState state = new TriangleMapParseState(scrolls); DisplayListRegion dlRegion = (DisplayListRegion)region; TriangleMap 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(); 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, state.vertexBytes, new ScrollFactory(scrolls)); 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); }
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 FixParse_cmdFC(ROM rom, DisplayListRegion region, RegionFixState state) { if (!state.config.fixCombiners) { return; } if (state.FCCountFixed != 0) { return; } CombinerCommand cmd = CombinerCommand.GetNewCombiner(region); UInt64 FCCmd = cmd.GetFCcmd(); if (FCCmd != 0) { state.FCCountFixed++; rom.Write64(FCCmd); } }
private static void RelocationParse_cmdFC(ROM rom, RelocationTable table, DisplayListRegion region) { if (!region.DLFixesNeeded) { return; } UInt64 FCcmd = 0; if (region.FCCountFixed == 0) { if (region.isFogEnabled) { if ((ulong)region.B9cmdfirst == 0xB900031DC8112078) { FCcmd = 0xFC127FFFFFFFF838; } if ((ulong)region.B9cmdfirst == 0xB900031DC8113078) { FCcmd = 0xFCFFFFFFFFFCF238; } if (region.isEnvcolorEnabled) { FCcmd = 0xFC127FFFFFFFFA38; } } else { if (region.FCCount == 1) { FCcmd = 0xFC127E24FFFFF9FC; } else { if (!region.isEnvcolorEnabled) { FCcmd = 0xFC121824FF33FFFF; } else { FCcmd = 0xFC122E24FFFFFBFD; } } } } else { FCcmd = 0xFC127E24FFFFF9FC; } if (FCcmd == 0) { MessageBox.Show("Parser could not choose the right combiner! Combiners won't be fixed", "Display List", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { region.FCCountFixed++; rom.Write64(FCcmd); } }