private static List <PointerText> LoadNewTranslationLines(RomDataWrapper rom) { var sw = new Stopwatch(); sw.Start(); var translatedLines = new List <PointerText>(); var lockObject = new Object(); var numThreads = Environment.ProcessorCount; var numPerThread = newTranslationLines.Count / numThreads; var tasks = new List <Task>(); for (int i = 0; i < numThreads - 1; i++) { var linesToHandle = newTranslationLines.Skip(i * numPerThread).Take(numPerThread); tasks.Add(Task.Run(() => LoadNewTranslationLinesTask(rom, linesToHandle, translatedLines, lockObject, newTranslationLines.Count))); } var finalLinesToHandle = newTranslationLines.Skip((numThreads - 1) * numPerThread); tasks.Add(Task.Run(() => LoadNewTranslationLinesTask(rom, finalLinesToHandle, translatedLines, lockObject, newTranslationLines.Count))); Task.WaitAll(tasks.ToArray()); sw.Stop(); return(translatedLines); }
private static void FindStringPointers(String threadName, RomDataWrapper rom, int from, int to) { for (int i = from; i < to - 1; i++) { if (i % 10000 == 0) { SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); //Prevent system sleep. Console.WriteLine("Finding thread {0} {1:#0}% done", threadName, ((Decimal)(i - from) / (to - from)) * 100); } var readByte = rom.RomContents[i]; var nextByte = rom.RomContents[i + 1]; if (readByte == end && nextByte != end) { var possibleTxt = i + 1; if (existingtranslationLines.Contains(possibleTxt)) { continue; } if (rom.IsTextReference(possibleTxt)) { lock (newTranslationLinesLockObject) { newTranslationLines.Add(possibleTxt); } } } } }
static void Main(string[] args) { if (args.Length < 3) { throw new ArgumentException("Pass a rom file, advance text ini to parse and output file."); } var outputFile = new FileInfo(args[2]); if (outputFile.Exists) { throw new Exception("Output file already exists. Please specify another name."); } var foundText = new Dictionary <Int32, PointerText>(); var rom = new RomDataWrapper(new FileInfo(args[0])); var bpre = new FileInfo(args[1]); String bpreContents; using (var reader = bpre.OpenText()) { bpreContents = reader.ReadToEnd(); } var expr = new Regex("[0-9A-F]{6}"); var exprMatches = expr.Matches(bpreContents); var sw = new Stopwatch(); sw.Start(); foreach (Match match in exprMatches) { if (Int32.TryParse(match.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out int intValue)) { if (foundText.ContainsKey(intValue)) { Console.WriteLine("Pointer {0:X6} appears multiple times in BPRE, will be skipped.", intValue); } else { var text = rom.GetOriginalPointerInfo(intValue); text.Group = FindGroup(bpreContents, match.Index); foundText.Add(intValue, text); } } } PointerText.WritePointersToFile(outputFile, foundText.Values); sw.Stop(); Console.WriteLine("On {0} searches searching took {1}", exprMatches.Count, sw.Elapsed); }
private static void FindStringPointers(String threadName, RomDataWrapper rom, int from, int to) { int prevEnd = from; for (int i = from; i < to; i++) { if (i % 10000 == 0) { SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS); //Prevent system sleep. Console.WriteLine("Finding thread {0} {1:#0}% done", threadName, ((Decimal)(i - from) / (to - from)) * 100); } var readByte = rom.RomContents[i]; if (readByte == end) { if (i - prevEnd > minStringLength) { var possibleTxt = prevEnd + 1; if (existingtranslationLines.Contains(possibleTxt)) { continue; } if (rom.IsTextReference(possibleTxt)) { lock (newTranslationLinesLockObject) { newTranslationLines.Add(possibleTxt); } } else { var backSearchLimit = (i - prevEnd < backSearch) ? i - prevEnd : backSearch; for (int j = i - 1; j > (i - backSearchLimit + 1); j--) { if (rom.IsTextReference(j)) { lock (newTranslationLinesLockObject) { newTranslationLines.Add(j); } break; //we stop after first found pointer. } } } } prevEnd = i; } } }
private static void LoadNewTranslationLinesTask(RomDataWrapper rom, IEnumerable <Int32> linesToGet, List <PointerText> linestotranslate, Object lockObject, Int32 totalCount) { foreach (var line in linesToGet) { var lineTotranslate = rom.GetOriginalPointerInfo(line); lock (lockObject) { linestotranslate.Add(lineTotranslate); if (linestotranslate.Count % 100 == 0) { Console.Write("\rReading progress: {0:##0}% ", ((Decimal)linestotranslate.Count / totalCount) * 100); } } } }
private static void ApplyTranslation(RomDataWrapper rom, List <PointerText> translatedLines) { var repointLocation = Int32.Parse(ConfigurationManager.AppSettings["EmptySpacestart"], NumberStyles.HexNumber); foreach (var translatedLine in translatedLines.Where(l => l.MustRepointReference)) { rom.ClearByteRange(translatedLine.Address, translatedLine.AvailableLength); rom.ModifyTextReferences(repointLocation, translatedLine.References); rom.WriteBytes(repointLocation, translatedLine.TranslatedSingleLineBytes); repointLocation += translatedLine.TranslatedSingleLineBytes.Length + 1; } foreach (var translatedLine in translatedLines.Where(l => !l.MustRepointReference)) { rom.WriteBytes(translatedLine.Address, translatedLine.TranslatedSingleLineBytes); rom.ClearByteRange(translatedLine.Address + translatedLine.TranslatedSingleLineBytes.Length, 1); } }
static void Main(string[] args) { if (args.Length < 3) { throw new ArgumentException("Pass a rom file, an existing translation file and an output file."); } var rom = new RomDataWrapper(new FileInfo(args[0])); var tmpRomData = new Byte[rom.RomContents.Length - (skipBlockEnd - skipBlockStart)]; Array.Copy(rom.RomContents, tmpRomData, skipBlockStart); Array.Copy(rom.RomContents, skipBlockEnd, tmpRomData, skipBlockStart, rom.RomContents.Length - skipBlockEnd); var romWithHole = new RomDataWrapper(tmpRomData); existingtranslationLines = LoadTranslationBaseLines(args[1]); if (existingtranslationLines == null) { existingtranslationLines = new List <Int32>(); } for (int i = 0; i < existingtranslationLines.Count; i++) { if (existingtranslationLines[i] > skipBlockEnd) { existingtranslationLines[i] -= (skipBlockEnd - skipBlockStart); } } var outputFile = new FileInfo(args[2]); if (outputFile.Exists) { throw new Exception(String.Format("The output file {0} already exists.", args[2])); } var sw = new Stopwatch(); sw.Start(); var numThreads = Environment.ProcessorCount; var numPerThread = (romWithHole.RomContents.Length - startPosition) / numThreads; var tasks = new List <Task>(); for (int i = 0; i < numThreads - 1; i++) { var name = "FT" + (i + 1); var from = startPosition + numPerThread * i; var to = startPosition + numPerThread * (i + 1); tasks.Add(Task.Run(() => FindStringPointers(name, romWithHole, from, to))); } tasks.Add(Task.Run(() => FindStringPointers("FT" + numThreads, romWithHole, startPosition + numPerThread * (numThreads - 1), romWithHole.RomContents.Length))); Task.WaitAll(tasks.ToArray()); sw.Stop(); Console.WriteLine("Finding text in {0} bytes took {1}", romWithHole.RomContents.Length, sw.Elapsed); for (int i = 0; i < newTranslationLines.Count; i++) { if (newTranslationLines[i] > skipBlockStart) { newTranslationLines[i] += (skipBlockEnd - skipBlockStart); } } var linesToTranslate = LoadNewTranslationLines(rom); Console.Write("\rReading progress: 100% "); Console.WriteLine(); Console.WriteLine("Writing missed text entries to file."); PointerText.WritePointersToFile(outputFile, linesToTranslate.OrderBy(l => l.Address)); Console.WriteLine("Done, press any key to continue..."); Console.ReadLine(); }
static Int32 Main(string[] args) { log.InfoFormat("Translation process started, passed args [{0}]", String.Join(" ", args.Select(s => "\"" + s + "\""))); if (args.Length < 3) { return(PrintUsage()); } var rom = new RomDataWrapper(new FileInfo(args[0])); var translationFileLines = LoadTranslationFileLines(args[1]); if (translationFileLines == null) { return(PrintUsage()); } var outputRom = new FileInfo(args[2]); if (args.Length > 3 && args[3].Equals("Execute", StringComparison.InvariantCultureIgnoreCase)) { isDryrun = false; } if (args.Length > 4 && args[4].Equals("Force", StringComparison.InvariantCultureIgnoreCase)) { forceRepointing = true; } log.Info("Preparing translated lines."); Console.WriteLine("Preparing translated lines."); List <PointerText> translatedLines = PrepareTranslatedLines(translationFileLines); Console.WriteLine(); log.Info("Searching lines that need repointing."); Console.WriteLine("Searching lines that need repointing."); //If we want to repoint as few lines as possible we must process lines bottom up. //This way if a line needs to be repointed, but fits due to the line afterwards being repointed already //the line can extend into the space previously occupied by the already repointed line. translatedLines = translatedLines.OrderByDescending(t => t.Address).ToList(); //find lines that need repointing RepointLinesIfRequired(translatedLines); translatedLines = translatedLines.OrderBy(l => l.Address).ToList(); //When actually modifying the rom data we go in order. log.Info("Will repoint these lines:"); Console.WriteLine("Will repoint these lines:"); foreach (var translatedLine in translatedLines.Where(l => l.MustRepointReference)) { log.Info(translatedLine); Console.WriteLine(translatedLine); } ApplyTranslation(rom, translatedLines); if (!isDryrun) { rom.WriteRomToFile(outputRom); } return(0); }