Skip to content

Instantly share code, notes, and snippets.

@ZingBallyhoo
Created June 27, 2019 17:33
Show Gist options
  • Save ZingBallyhoo/5846323b36844cc0f0013b17a5895590 to your computer and use it in GitHub Desktop.
Save ZingBallyhoo/5846323b36844cc0f0013b17a5895590 to your computer and use it in GitHub Desktop.
// structgen
// generates simple vtable structures for directx objects
// run in a linqpad query or whatever
class VTableInfo {
public readonly string Name;
public readonly List<string> Methods;
public VTableInfo(string name) {
Name = name;
Methods = new List<string>();
}
}
void Main()
{
const string dir = @"<directory with header file names>"; // copy whatever you need from include path
const string file = "dxgi"; // header file name
var structNameRegex = new Regex(@"typedef struct ([^\s]*)");
var interfaceNameRegex = new Regex(@"interface ([^\s]*)");
var methodNameRegex = new Regex(@"[*]([^\s]*)");
string currentName = null;
bool hasBegun = false;
bool waitForSemi = false;
List<VTableInfo> vTables = new List<VTableInfo>();
VTableInfo currentVTable = null;
using (StreamReader reader = new StreamReader(Path.Combine(dir, file+".h"))) {
foreach (string rawLine in reader.ReadToEnd().Split('\n')) {
if (string.IsNullOrWhiteSpace(rawLine)) continue;
var line = rawLine.Trim();
if (!hasBegun) {
if (line.Contains("typedef struct")) {
currentName = structNameRegex.Match(line).Groups[1].Value;
}
if (line.Contains("BEGIN_INTERFACE")) {
hasBegun = true;
currentVTable = new VTableInfo(currentName);
vTables.Add(currentVTable);
}
} else {
if (line.Contains("END_INTERFACE")) {
hasBegun = false;
continue;
}
if (!waitForSemi) {
var match = methodNameRegex.Match(line);
currentVTable.Methods.Add(match.Groups[1].Value);
waitForSemi = true;
} else if (line.Contains(';')) {
waitForSemi = false;
}
}
}
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < vTables.Count; i++) {
if (i != 0) builder.AppendLine();
var vTable = vTables[i];
builder.AppendLine($"typedef struct {vTable.Name} {{");
for (int j = 0; j < vTable.Methods.Count; j++) {
builder.AppendLine($" void* {vTable.Methods[j]}; // {j*8}");
}
builder.AppendLine($"}} {vTable.Name};");
}
using (StreamWriter writer = new StreamWriter(Path.Combine(dir, file + "_vtable.h"))) {
writer.Write(builder.ToString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment