From 9af8935f471399cea395e5717032520de1505038 Mon Sep 17 00:00:00 2001 From: Garry Newman Date: Wed, 17 Apr 2019 13:53:54 +0100 Subject: [PATCH] Overloaded function vtable order --- .../Generated/Interfaces/ISteamUserStats.cs | 20 +++++------ Generator/CodeWriter/ClassVTable.cs | 35 ++++++++++++++++++- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs index 494794e..90b1618 100644 --- a/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamUserStats.cs @@ -18,10 +18,10 @@ namespace Steamworks public override void InitInternals() { _RequestCurrentStats = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 0) ); - _GetStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 8) ); - _GetStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 16) ); - _SetStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 24) ); - _SetStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 32) ); + _GetStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 16) ); + _GetStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 8) ); + _SetStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 32) ); + _SetStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 24) ); _UpdateAvgRateStat = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 40) ); _GetAchievement = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 48) ); _SetAchievement = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 56) ); @@ -34,8 +34,8 @@ namespace Steamworks _GetNumAchievements = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 112) ); _GetAchievementName = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 120) ); _RequestUserStats = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 128) ); - _GetUserStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 136) ); - _GetUserStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 144) ); + _GetUserStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 144) ); + _GetUserStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 136) ); _GetUserAchievement = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 152) ); _GetUserAchievementAndUnlockTime = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 160) ); _ResetAllStats = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 168) ); @@ -56,10 +56,10 @@ namespace Steamworks _GetNextMostAchievedAchievementInfo = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 288) ); _GetAchievementAchievedPercent = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 296) ); _RequestGlobalStats = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 304) ); - _GetGlobalStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 312) ); - _GetGlobalStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 320) ); - _GetGlobalStatHistory1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 328) ); - _GetGlobalStatHistory2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 336) ); + _GetGlobalStat1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 320) ); + _GetGlobalStat2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 312) ); + _GetGlobalStatHistory1 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 336) ); + _GetGlobalStatHistory2 = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 328) ); } #region FunctionMeta diff --git a/Generator/CodeWriter/ClassVTable.cs b/Generator/CodeWriter/ClassVTable.cs index 2293a54..7dc30fd 100644 --- a/Generator/CodeWriter/ClassVTable.cs +++ b/Generator/CodeWriter/ClassVTable.cs @@ -57,17 +57,50 @@ namespace Generator 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 ); + } + StartBlock( $"public override void InitInternals()" ); { for (int i=0; i< clss.Functions.Count; i++ ) { var func = clss.Functions[i]; - WriteLine( $"_{func.Name} = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, {i*8}) );" ); + WriteLine( $"_{func.Name} = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, {locations[i]}) );" ); } } EndBlock(); } + 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; + } + private void WriteFunction( CodeParser.Class clss, CodeParser.Class.Function func ) { var returnType = BaseType.Parse( func.ReturnType );