public int CompareTo(Object o) { StringEntry e = (StringEntry)o; return(identifier.CompareTo(e.identifier)); }
static void DumpScript(String filename, String sfxDir, String outputDir = "scripts") { String roomName = filename.Substring(0, filename.IndexOf('.')); roomName = roomName.Substring(roomName.LastIndexOf('/')); byte[] data = File.ReadAllBytes(filename); int startOffset = Helper.ReadUInt16(data, 14); int endOffset = Helper.ReadUInt16(data, 16); // Dump RDF file FileStream stream = System.IO.File.Create(outputDir + "/" + roomName + ".RDF"); stream.Write(data, 0, data.Length); stream.Close(); String outFile = outputDir + "/" + roomName + ".txt"; File.Delete(outFile); var stringList = new List <StringEntry>(); IEnumerable <String> sfxList = new List <String>(); if (sfxDir != null) { sfxList = Directory.GetFiles(sfxDir).Select(x => { x = x.Replace(".voc", ""); x = x.Replace(".VOC", ""); int pos = x.LastIndexOf('/'); if (pos == -1) { return(x); } return(x.Substring(pos + 1)); }); } // First pass: search for strings int offset = 0; while (offset < data.Length) { int so = offset; if (((char)(data[offset])) == '#') // Search for audio markers { offset++; int backslashes = 0; while (offset < data.Length && ((char)data[offset]) != '#' && data[offset] != '\0') { if (data[offset] == '\\') { backslashes++; } offset++; } if (offset == data.Length || data[offset] != '#' || backslashes != 1) { continue; } string s = Helper.GetStringFromBuf(data, so); string id = ""; for (offset = so + 1; offset < data.Length && data[offset] != '#'; offset++) { id += (char)data[offset]; } stringList.Add(new StringEntry(so, so + s.Length + 1, s, id)); offset = so + s.Length; } else // Search for known filenames { string s = Helper.GetStringFromBuf(data, offset); foreach (string f in sfxList) { if (String.Equals(s, f, StringComparison.OrdinalIgnoreCase)) { offset += f.Length; stringList.Add(new StringEntry(so, offset + 1, s, "")); break; } } } offset++; } // Dump each script into the txt file HashSet <UInt32> seenEvents = new HashSet <UInt32>(); offset = startOffset; int slIndex = 0; while (offset < endOffset) { UInt32 index = Helper.ReadUInt32(data, offset); int nextOffset = Helper.ReadUInt16(data, offset + 4); if (seenEvents.Contains(index)) { Console.WriteLine("WARNING: Event duplicated: \"" + EventToString(index, offset) + "\""); } seenEvents.Add(index); String infoString; // When the last "code index" is passed, there's no indication of it, // so I need to check for invalid values if (nextOffset > endOffset || nextOffset < offset + 6) { infoString = "\n\n=====================\n" + "Helper code\n" + "=====================\n"; nextOffset = endOffset; } else { infoString = "\n\n=====================\n" + "Event: " + EventToString(index, offset) + "\n" + "=====================\n"; offset += 6; } Helper.RunBashCommand("echo '" + infoString + "' >> " + outFile); while (slIndex < stringList.Count && stringList[slIndex].end <= offset) { slIndex++; } while (offset < nextOffset) { if (slIndex < stringList.Count && stringList[slIndex].start == offset) { StringEntry ent = stringList[slIndex]; Helper.AppendToFile(outFile, "\nString (0x" + ent.start.ToString("X4") + "): '" + ent.str + "'"); offset = ent.end; slIndex++; } else if (slIndex < stringList.Count && stringList[slIndex].start < nextOffset) { int end = stringList[slIndex].start; Helper.Objdump(filename, outFile, offset, end); offset = end; } else { Helper.Objdump(filename, outFile, offset, nextOffset); break; } } offset = nextOffset; } stream.Close(); // Print unsorted string list (must be done after objdump calls) Console.WriteLine("\n====================\nUnsorted strings:\n===================="); foreach (StringEntry e in stringList) { if (e.identifier.Length == 0) { continue; } Console.Write(e.start.ToString("X4") + ": "); Console.WriteLine("\"" + e.str.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\","); } // Print sorted string list (must be done after objdump calls) stringList.Sort(); Console.WriteLine("\n====================\nSorted strings:\n===================="); foreach (StringEntry e in stringList) { if (e.identifier.Length == 0) { continue; } Console.WriteLine("\"" + e.str.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\","); } // Print out the strings to be copied into an enum Console.WriteLine("\n====================\nEnum:\n===================="); Console.WriteLine("\nenum Strings {"); foreach (StringEntry e in stringList) { if (e.identifier.Length == 0) { continue; } Console.WriteLine("TX_" + e.identifier + ","); } Console.WriteLine("}"); }