using System; using System.IO; using System.Text; using System.Text.RegularExpressions; namespace Generator { static class Generator { public static string RaylibDirectory = "C:\\raylib\\raylib\\"; public static string RaylibDirectory2 = "C:\\Users\\Chris\\Documents\\projects\\raylib\\"; // string extensions private static string CapitalizeFirstCharacter(string format) { if (string.IsNullOrEmpty(format)) return string.Empty; else return char.ToUpper(format[0]) + format.ToLower().Substring(1); } public static string Indent(this string value, int size) { var strArray = value.Split('\n'); var sb = new StringBuilder(); foreach (var s in strArray) sb.Append(new string(' ', size)).Append(s); return sb.ToString(); } // testing regex public static string ReplaceEx(this string input, string pattern, string replacement) { var matches = Regex.Matches(input, pattern); foreach (Match match in matches) { //Console.WriteLine(match.Value); } return Regex.Replace(input, pattern, replacement); } // Create binding code public static void Process(string filePath, string api) { var lines = File.ReadAllLines(RaylibDirectory + "src//" + filePath); var output = ""; output += "using Raylib;\n"; output += "using static Raylib.Raylib;\n\n"; output += "public partial class Examples\n{\n"; // convert functions to c# foreach (string line in lines) { if (line.StartsWith(api)) { output += "\t\t[DllImport(nativeLibName)]\n"; string newLine = line.Clone().ToString(); newLine = newLine.Replace(api, "public static extern"); // add converted function output += "\t\t" + newLine + "\n\n"; } } output += "\t\t#endregion\n"; //output += text; output += "\n}"; output = output.Replace("(void)", "()"); output = output.Replace("const char *", "string "); output = output.Replace("const char * ", "string"); output = output.Replace("const char*", "string"); output = output.Replace("unsigned int", "uint"); output = output.Replace("unsigned char", "byte"); output = output.Replace("const void *", "byte[] "); output = output.Replace("const float *", "float[] "); output = output.Replace("const int *", "int[] "); output = output.Replace("...", "params object[] args"); output = output.Replace("Music ", "IntPtr "); Console.WriteLine(output); filePath = Path.GetFileNameWithoutExtension(filePath); filePath = CapitalizeFirstCharacter(filePath); Directory.CreateDirectory("Raylib-cs"); File.WriteAllText("Raylib-cs/ " + filePath + ".cs", output); } // Convert c style to c# // Design is close to raylib so only a few changes needed public static void ProcessExample(string file, string folder, string path) { // load and setup var fileName = Path.GetFileNameWithoutExtension(file); var text = File.ReadAllText(file); var result = ""; var output = ""; output += "using Raylib;\n"; output += "using static Raylib.Raylib;\n\n"; output += "public partial class " + folder + "\n{\n"; // text = text.Replace("\r", "\r\n"); // rough file conversion string[] lines = text.Split('\n'); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; // ignore certain preprocess symbols if (line.Contains("#include")) continue; else if (line.Contains("#if")) continue; else if (line.Contains("#else")) continue; else if (line.Contains("#endif")) continue; else if (line.Contains("#define")) { var str = line.Replace("#define", ""); var arr = str.Trim().Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (arr.Length < 2) continue; bool isNumeric = int.TryParse(arr[1], out var n); if (isNumeric) result += "public const int " + arr[0] + " = " + arr[1] + ";\r\n"; else result += "public const string " + arr[0] + " = " + arr[1] + ";\r\n"; } // change main signature else if (line.StartsWith("int main")) result += "public static void Main()\r\n"; // remove typedef and mark members as public else if (line.StartsWith("typedef struct")) { var members = ""; while (!line.StartsWith("}")) { i++; line = lines[i]; members += "public " + line + "\n"; } line = line.Replace(" ", ""); line = line.Replace("}", ""); line = line.Replace(";", ""); result += "struct " + line + "{\n\n"; result += members; } // copy line by default else result += line + "\n"; } // regex // (Type){...} -> new Type(...) // e.g (Vector2){ 100, 100 } -> new Vector2( 100, 100 ); result = result.ReplaceEx(@"\((\w+)\){(.*)}", @"new $1($2);"); result = result.ReplaceEx(@"\((\w+)\) \w+ = {(.*)}", @"new $1($2);"); // Type name[size] -> Type[] name = new Type[size]; // e.g Rectangle buildings[MAX_BUILDINGS]; -> Rectangle[] buildings = new Rectangle[MAX_BUILDINGS]; result = result.ReplaceEx(@"(\w+) (\w+)\[(.*)\];", "$1[] $2 = new $1[$3];"); result = result.Replace("Music ", "IntPtr "); result = result.Replace("(void)", "()"); // defines to enums(might use defines as variables aswell not sure) result = result.ReplaceEx(@"KEY_(\w+)", @"(int)Key.$1"); result = result.ReplaceEx(@"MOUSE_(\w+)", @"(int)Mouse.$1"); result = result.ReplaceEx(@"FLAG_(\w+)", @"(int)Flag.$1"); // result = result.ReplaceEx(@"FLAG_(\w+)", @"(int)Flag.$1"); // add result result = result.Indent(4); output += result; output += "\n}\n"; // saves relative to executable location var loc = path + "//" + fileName + ".cs"; File.WriteAllText(loc, output); Console.WriteLine("Generated " + fileName + ".cs"); } } }