private void Swap(CodeParser.Class clss, string v1, string v2, int[] locations) { var a = clss.Functions.IndexOf(clss.Functions.Single(x => x.Name == v1)); var b = clss.Functions.IndexOf(clss.Functions.Single(x => x.Name == v2)); var s = locations[a]; locations[a] = locations[b]; locations[b] = s; }
void WriteFunctionPointerReader(CodeParser.Class clss) { // TODO - we'll probably have to do this PER platform int[] standardLocations = new int[clss.Functions.Count]; int[] windowsLocations = new int[clss.Functions.Count]; for (int i = 0; i < clss.Functions.Count; i++) { windowsLocations[i] = i * 8; standardLocations[i] = i * 8; } // // MSVC switches the order in the vtable of overloaded functions // I'm not going to try to try to work out how to order shit // so lets just manually fix shit here // if (clss.Name == "ISteamUserStats") { Swap(clss, "GetStat1", "GetStat2", windowsLocations); Swap(clss, "SetStat1", "SetStat2", windowsLocations); Swap(clss, "GetUserStat1", "GetUserStat2", windowsLocations); Swap(clss, "GetGlobalStat1", "GetGlobalStat2", windowsLocations); Swap(clss, "GetGlobalStatHistory1", "GetGlobalStatHistory2", windowsLocations); } if (clss.Name == "ISteamGameServerStats") { Swap(clss, "GetUserStat1", "GetUserStat2", windowsLocations); Swap(clss, "SetUserStat1", "SetUserStat2", windowsLocations); } if (clss.Name == "ISteamUGC") { Swap(clss, "CreateQueryAllUGCRequest1", "CreateQueryAllUGCRequest2", windowsLocations); } StartBlock($"public override void InitInternals()"); { var different = new List <int>(); for (int i = 0; i < clss.Functions.Count; i++) { var func = clss.Functions[i]; if (Cleanup.IsDeprecated($"{clss.Name}.{func.Name}")) { WriteLine($" // {func.Name} is deprecated"); } else { if (standardLocations[i] != windowsLocations[i]) { different.Add(i); continue; } WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, Platform.MemoryOffset( {standardLocations[i]} ) ) );"); } } if (different.Count > 0) { WriteLine(""); WriteLine("#if PLATFORM_WIN"); foreach (var i in different) { var func = clss.Functions[i]; WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, Platform.MemoryOffset( {windowsLocations[i]} ) ) );"); } WriteLine("#else"); foreach (var i in different) { var func = clss.Functions[i]; WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, Platform.MemoryOffset( {standardLocations[i]} ) ) );"); } WriteLine("#endif"); } } EndBlock(); StartBlock($"internal override void Shutdown()"); { WriteLine($"base.Shutdown();"); WriteLine(""); for (int i = 0; i < clss.Functions.Count; i++) { var func = clss.Functions[i]; var returnType = BaseType.Parse(func.ReturnType); var args = func.Arguments.Select(x => BaseType.Parse(x.Value, x.Key)).ToArray(); var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (Cleanup.IsDeprecated($"{clss.Name}.{func.Name}")) { continue; } WriteLine($"_{func.Name} = null;"); } } EndBlock(); }
private void WriteFunction(CodeParser.Class clss, CodeParser.Class.Function func) { var returnType = BaseType.Parse(func.ReturnType); returnType.Func = func.Name; var args = func.Arguments.Select(x => { var bt = BaseType.Parse(x.Value, x.Key); bt.Func = func.Name; return(bt); }).ToArray(); var argstr = string.Join(", ", args.Select(x => x.AsArgument())); var delegateargstr = string.Join(", ", args.Select(x => x.AsArgument())); var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (returnType is SteamApiCallType sap) { sap.CallResult = func.CallResult; argstr = string.Join(", ", args.Select(x => x.AsArgument().Replace("ref ", " /* ref */ "))); } WriteLine($"#region FunctionMeta"); WriteLine($"[UnmanagedFunctionPointer( Platform.MemberConvention )]"); if (returnType.ReturnAttribute != null) { WriteLine(returnType.ReturnAttribute); } if (returnType.IsReturnedWeird) { WriteLine("#if PLATFORM_WIN"); WriteLine($"private delegate void F{func.Name}( IntPtr self, ref {returnType.TypeName} retVal, {delegateargstr} );".Replace(" retVal, )", " retVal )")); WriteLine("#else"); } WriteLine($"private delegate {returnType.TypeNameFrom} F{func.Name}( IntPtr self, {delegateargstr} );".Replace("( IntPtr self, )", "( IntPtr self )")); if (returnType.IsReturnedWeird) { WriteLine("#endif"); } WriteLine($"private F{func.Name} _{func.Name};"); WriteLine(); WriteLine($"#endregion"); StartBlock($"internal {returnType.ReturnType} {func.Name}( {argstr} )".Replace("( )", "()")); { var callargs = string.Join(", ", args.Select(x => x.AsCallArgument())); if (returnType.IsReturnedWeird) { WriteLine("#if PLATFORM_WIN"); { WriteLine($"var retVal = default( {returnType.TypeName} );"); WriteLine($"_{func.Name}( Self, ref retVal, {callargs} );".Replace(", );", " );")); WriteLine($"{returnType.Return( "retVal" )}"); } WriteLine("#else"); } if (returnType.IsVoid) { WriteLine($"_{func.Name}( Self, {callargs} );".Replace("( Self, )", "( Self )")); } else { var v = $"_{func.Name}( Self, {callargs} )".Replace("( Self, )", "( Self )"); WriteLine(returnType.Return(v)); } if (returnType.IsReturnedWeird) { WriteLine("#endif"); } } EndBlock(); }
void WriteFunctionPointerReader(CodeParser.Class clss) { // TODO - we'll probably have to do this PER platform int[] locations = new int[clss.Functions.Count]; for (int i = 0; i < clss.Functions.Count; i++) { locations[i] = i * 8; } // // MSVC switches the order in the vtable of overloaded functions // I'm not going to try to try to work out how to order shit // so lets just manually fix shit here // if (clss.Name == "ISteamUserStats") { Swap(clss, "GetStat1", "GetStat2", locations); Swap(clss, "SetStat1", "SetStat2", locations); Swap(clss, "GetUserStat1", "GetUserStat2", locations); Swap(clss, "GetGlobalStat1", "GetGlobalStat2", locations); Swap(clss, "GetGlobalStatHistory1", "GetGlobalStatHistory2", locations); } if (clss.Name == "ISteamUGC") { Swap(clss, "CreateQueryAllUGCRequest1", "CreateQueryAllUGCRequest2", locations); } StartBlock($"public override void InitInternals()"); { for (int i = 0; i < clss.Functions.Count; i++) { var func = clss.Functions[i]; var returnType = BaseType.Parse(func.ReturnType); var args = func.Arguments.Select(x => BaseType.Parse(x.Value, x.Key)).ToArray(); var regularpos = i * 8; var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (Cleanup.IsDeprecated($"{clss.Name}.{func.Name}")) { WriteLine($" // {func.Name} is deprecated - {locations[i]}"); } else { var pos = $"Config.Os == OsType.Windows ? {locations[i]} : {regularpos} "; if (regularpos == locations[i]) { pos = regularpos.ToString(); } WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, {pos}) );"); if (windowsSpecific) { WriteLine($"_{func.Name}_Windows = Marshal.GetDelegateForFunctionPointer<F{func.Name}_Windows>( Marshal.ReadIntPtr( VTable, {pos}) );"); } } } } EndBlock(); StartBlock($"internal override void Shutdown()"); { WriteLine($"base.Shutdown();"); WriteLine(""); for (int i = 0; i < clss.Functions.Count; i++) { var func = clss.Functions[i]; var returnType = BaseType.Parse(func.ReturnType); var args = func.Arguments.Select(x => BaseType.Parse(x.Value, x.Key)).ToArray(); var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (Cleanup.IsDeprecated($"{clss.Name}.{func.Name}")) { continue; } WriteLine($"_{func.Name} = null;"); if (windowsSpecific) { WriteLine($"_{func.Name}_Windows = null;"); } } } EndBlock(); }
private void WriteFunction(CodeParser.Class clss, CodeParser.Class.Function func) { var returnType = BaseType.Parse(func.ReturnType); returnType.Func = func.Name; var args = func.Arguments.Select(x => { var bt = BaseType.Parse(x.Value, x.Key); bt.Func = func.Name; return(bt); }).ToArray(); var argstr = string.Join(", ", args.Select(x => x.AsArgument())); var delegateargstr = string.Join(", ", args.Select(x => x.AsArgument())); var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (returnType is SteamApiCallType sap) { sap.CallResult = func.CallResult; argstr = string.Join(", ", args.Select(x => x.AsArgument().Replace("ref ", " /* ref */ "))); } WriteLine($"#region FunctionMeta"); WriteLine($"[UnmanagedFunctionPointer( CallingConvention.ThisCall )]"); if (returnType.ReturnAttribute != null) { WriteLine(returnType.ReturnAttribute); } WriteLine($"private delegate {returnType.TypeNameFrom} F{func.Name}( IntPtr self, {delegateargstr} );".Replace("( IntPtr self, )", "( IntPtr self )")); WriteLine($"private F{func.Name} _{func.Name};"); if (windowsSpecific) { var delegateargstrw = string.Join(", ", args.Select(x => x.AsWinArgument())); WriteLine($"[UnmanagedFunctionPointer( CallingConvention.ThisCall )]"); if (returnType.IsReturnedWeird) { var windelargs = $"ref {returnType.TypeName} retVal, {delegateargstrw}".Trim(',', ' '); WriteLine($"private delegate void F{func.Name}_Windows( IntPtr self, {windelargs} );".Replace("( IntPtr self, )", "( IntPtr self )")); } else { if (returnType.ReturnAttribute != null) { WriteLine(returnType.ReturnAttribute); } WriteLine($"private delegate {returnType.TypeNameFrom} F{func.Name}_Windows( IntPtr self, {delegateargstrw} );".Replace("( IntPtr self, )", "( IntPtr self )")); } WriteLine($"private F{func.Name}_Windows _{func.Name}_Windows;"); } WriteLine(); WriteLine($"#endregion"); StartBlock($"internal {returnType.ReturnType} {func.Name}( {argstr} )".Replace("( )", "()")); { var callargs = string.Join(", ", args.Select(x => x.AsCallArgument())); if (returnType.IsReturnedWeird) { StartBlock("if ( Config.Os == OsType.Windows )"); { WriteLine($"var retVal = default( {returnType.TypeName} );"); WriteLine($"_{func.Name}_Windows( Self, ref retVal, {callargs} );".Replace(", );", " );")); WriteLine($"{returnType.Return( "retVal" )}"); } EndBlock(); WriteLine(); } else if (windowsSpecific) { StartBlock("if ( Config.Os == OsType.Windows )"); { var wincallargs = callargs; foreach (var arg in args) { if (!arg.WindowsSpecific) { continue; } if (arg.IsVector) { WriteLine($"{arg.TypeName}.Pack8[] {arg.VarName}_windows = {arg.VarName};"); } else { WriteLine($"{arg.TypeName}.Pack8 {arg.VarName}_windows = {arg.VarName};"); } wincallargs = wincallargs.Replace($" {arg.VarName}", $" {arg.VarName}_windows"); } if (!returnType.IsVoid) { Write("var retVal = "); } WriteLine($"_{func.Name}_Windows( Self, {wincallargs} );".Replace("( Self, )", "( Self )")); foreach (var arg in args) { if (!arg.WindowsSpecific) { continue; } WriteLine($"{arg.VarName} = {arg.VarName}_windows;"); } if (!returnType.IsVoid) { WriteLine(returnType.Return("retVal")); } } EndBlock(); WriteLine(); } if (returnType.IsVoid) { WriteLine($"_{func.Name}( Self, {callargs} );".Replace("( Self, )", "( Self )")); } else { var v = $"_{func.Name}( Self, {callargs} )".Replace("( Self, )", "( Self )"); WriteLine(returnType.Return(v)); } } EndBlock(); }
private void WriteFunction(CodeParser.Class clss, CodeParser.Class.Function func) { var returnType = BaseType.Parse(func.ReturnType); returnType.Func = func.Name; var args = func.Arguments.Select(x => { var bt = BaseType.Parse(x.Value, x.Key); bt.Func = func.Name; return(bt); }).ToArray(); for (int i = 0; i < args.Length; i++) { if (args[i] is StringType) { if (args[i + 1] is IntType || args[i + 1] is UIntType) { if (args[i + 1].Ref == string.Empty) { args[i + 1] = new ConstValueType(args[i + 1], "(1024 * 32)"); } } else { throw new System.Exception($"String Builder Next Type Is {args[i+1].GetType()}"); } } } var argstr = string.Join(", ", args.Where(x => !x.ShouldSkipAsArgument).Select(x => x.AsArgument()));; var delegateargstr = string.Join(", ", args.Select(x => x.AsNativeArgument())); var windowsSpecific = NeedsWindowsSpecificFunction(func, returnType, args); if (returnType is SteamApiCallType sap) { sap.CallResult = func.CallResult; argstr = string.Join(", ", args.Select(x => x.AsArgument().Replace("ref ", " /* ref */ "))); } WriteLine($"#region FunctionMeta"); WriteLine($"[UnmanagedFunctionPointer( Platform.MemberConvention )]"); if (returnType.ReturnAttribute != null) { WriteLine(returnType.ReturnAttribute); } if (returnType.IsReturnedWeird) { WriteLine("#if PLATFORM_WIN"); WriteLine($"private delegate void F{func.Name}( IntPtr self, ref {returnType.TypeName} retVal, {delegateargstr} );".Replace(" retVal, )", " retVal )")); WriteLine("#else"); } WriteLine($"private delegate {returnType.TypeNameFrom} F{func.Name}( IntPtr self, {delegateargstr} );".Replace("( IntPtr self, )", "( IntPtr self )")); if (returnType.IsReturnedWeird) { WriteLine("#endif"); } WriteLine($"private F{func.Name} _{func.Name};"); WriteLine(); WriteLine($"#endregion"); StartBlock($"internal {returnType.ReturnType} {func.Name}( {argstr} )".Replace("( )", "()")); { var callargs = string.Join(", ", args.Select(x => x.AsCallArgument())); // // Code before any calls // foreach (var arg in args) { if (arg is StringType sb) { WriteLine($"IntPtr mem{sb.VarName} = Helpers.TakeMemory();"); } } // // The actual call // if (returnType.IsReturnedWeird) { WriteLine("#if PLATFORM_WIN"); { WriteLine($"var retVal = default( {returnType.TypeName} );"); WriteLine($"_{func.Name}( Self, ref retVal, {callargs} );".Replace(", );", " );")); WriteLine($"{returnType.Return( "retVal" )}"); } WriteLine("#else"); } if (returnType.IsVoid) { WriteLine($"_{func.Name}( Self, {callargs} );".Replace("( Self, )", "( Self )")); } else { WriteLine($"var returnValue = _{func.Name}( Self, {callargs} );".Replace("( Self, )", "( Self )")); } // // Code after the call // foreach (var arg in args) { if (arg is StringType sb) { WriteLine($"{sb.VarName} = Helpers.MemoryToString( mem{sb.VarName} );"); } } // // Return // if (!returnType.IsVoid) { WriteLine(returnType.Return("returnValue")); } if (returnType.IsReturnedWeird) { WriteLine("#endif"); } } EndBlock(); }
void WriteFunctionPointerReader(CodeParser.Class clss) { // TODO - we'll probably have to do this PER platform int[] locations = new int[clss.Functions.Count]; for (int i = 0; i < clss.Functions.Count; i++) { locations[i] = i * 8; } // // MSVC switches the order in the vtable of overloaded functions // I'm not going to try to try to work out how to order shit // so lets just manually fix shit here // if (clss.Name == "ISteamUserStats") { Swap(clss, "GetStat1", "GetStat2", locations); Swap(clss, "SetStat1", "SetStat2", locations); Swap(clss, "GetUserStat1", "GetUserStat2", locations); Swap(clss, "GetGlobalStat1", "GetGlobalStat2", locations); Swap(clss, "GetGlobalStatHistory1", "GetGlobalStatHistory2", locations); } if (clss.Name == "ISteamUGC") { Swap(clss, "CreateQueryAllUGCRequest1", "CreateQueryAllUGCRequest2", locations); } StartBlock($"public override void InitInternals()"); { for (int i = 0; i < clss.Functions.Count; i++) { var func = clss.Functions[i]; var returnType = BaseType.Parse(func.ReturnType); var regularpos = i * 8; if (Cleanup.IsDeprecated($"{clss.Name}.{func.Name}")) { WriteLine($" // {func.Name} is deprecated - {locations[i]}"); } else { if (regularpos != locations[i]) { WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, Config.Os == OsType.Windows ? {locations[i]} : {regularpos} ) );"); if (returnType.IsReturnedWeird) { throw new System.NotImplementedException(); } } else { WriteLine($"_{func.Name} = Marshal.GetDelegateForFunctionPointer<F{func.Name}>( Marshal.ReadIntPtr( VTable, {locations[i]}) );"); if (returnType.IsReturnedWeird) { WriteLine($"_{func.Name}_Windows = Marshal.GetDelegateForFunctionPointer<F{func.Name}_Windows>( Marshal.ReadIntPtr( VTable, {locations[i]}) );"); } } } } } EndBlock(); }