Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add some type commands to the disassembler #2151

Merged
merged 5 commits into from
Jan 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion DMDisassembler/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ static void Main(string[] args) {
case "d":
case "decompile": Decompile(split); break;
case "stats": Stats(GetArg()); break;
case "dump-types": DumpTypes(); break;
case "test-all": TestAll(); break;
case "dump-all": DumpAll(); break;
case "help": {
Expand Down Expand Up @@ -119,6 +120,7 @@ private static void PrintHelp([CanBeNull] string command) {
Console.WriteLine("Prints various statistics. Usage: stats [type]");
Console.WriteLine("Options for [type]:");
Console.WriteLine("procs-by-type : Prints the number of proc declarations (not overrides) on each type in descending order");
Console.WriteLine("subtypes-by-type : Prints the number of direct-descendant subtypes on each type in descending order");
Console.WriteLine("opcode-count : Prints the number of occurrences for each opcode in descending order");
break;
}
Expand All @@ -139,6 +141,7 @@ void AllCommands() {
Console.WriteLine("list procs|globals : List all globals, or all procs on a selected type");
Console.WriteLine("decompile|d [name] : Decompiles the proc on the selected type");
Console.WriteLine("stats [type] : Prints various stats about the game. Use \"help stats\" for more info");
Console.WriteLine("dump-types : Writes a list of every type to a file");
Console.WriteLine("dump-all : Decompiles every proc and writes the output to a file");
Console.WriteLine("test-all : Tries to decompile every single proc to check for issues with this disassembler; not for production use");
}
Expand All @@ -155,6 +158,10 @@ private static void Stats([CanBeNull] string statType) {
ProcsByType();
return;
}
case "subtypes-by-type": {
SubtypesByType();
return;
}
case "opcode-count": {
OpcodeCount();
return;
Expand Down Expand Up @@ -189,6 +196,40 @@ void ProcsByType() {
}
}

void SubtypesByType() {
Console.WriteLine("Counting all subtypes by type. This may take a moment.");
Dictionary<int, int> typeIdToSubtypeCount = new Dictionary<int, int>(TypesById.Count);

foreach (DMType type in TypesById) {
var parent = type.Json.Parent;
if (parent is null) continue;

if (typeIdToSubtypeCount.TryGetValue(parent.Value, out var count)) {
typeIdToSubtypeCount[parent.Value] = count + 1;
} else {
typeIdToSubtypeCount[parent.Value] = 1;
}
}

var outputFile = Path.ChangeExtension(JsonFile, ".txt")!;
var name = Path.GetFileName(outputFile);
var path = Path.GetDirectoryName(outputFile)!;
outputFile = Path.Combine(path, $"__od_subtypes-by-type_{name}");
using StreamWriter writer = new StreamWriter(outputFile, append: false, encoding: Encoding.UTF8, bufferSize: 65536);

writer.WriteLine("Type: Subtype Count");
foreach (var pair in typeIdToSubtypeCount.OrderByDescending(kvp => kvp.Value)) {
var type = TypesById[pair.Key];
if (pair.Key == 0) {
writer.WriteLine($"<global>: {pair.Value:n0}");
} else {
writer.WriteLine($"{type.Path}: {pair.Value:n0}");
}
}

Console.WriteLine($"Successfully dumped subtypes-by-type to {outputFile}");
}

void OpcodeCount() {
Console.WriteLine("Counting all opcode occurrences. This may take a moment.");
Dictionary<string, int> opcodeToCount = new Dictionary<string, int>();
Expand Down Expand Up @@ -374,6 +415,22 @@ private static int TestAll() {
return errored;
}

private static void DumpTypes() {
Console.WriteLine("Dumping all types. This may take a moment.");

var outputFile = Path.ChangeExtension(JsonFile, ".txt")!;
var name = Path.GetFileName(outputFile);
var path = Path.GetDirectoryName(outputFile)!;
outputFile = Path.Combine(path, $"__od_types_{name}");
using StreamWriter writer = new StreamWriter(outputFile, append: false, encoding: Encoding.UTF8, bufferSize: 65536);

foreach (DMType type in TypesById) {
writer.WriteLine(type.Path);
}

Console.WriteLine($"Successfully dumped {TypesById.Count:n0} types to {outputFile}");
}

private static void DumpAll() {
Console.WriteLine("Dumping all procs. This may take a moment.");
int errored = 0, all = 0;
Expand All @@ -394,7 +451,7 @@ private static void DumpAll() {
++all;
}

var procCount = errored > 0 ? $"{all - errored}/{all} ({errored} failed procs)" : $"all {all}";
var procCount = errored > 0 ? $"{(all - errored):n0}/{all:n0} ({errored:n0} failed procs)" : $"all {all:n0}";
Console.WriteLine($"Successfully dumped {procCount} procs to {outputFile}");
}

Expand Down
Loading