From 9cf553a7867f94eb5779afd76b15d4363291e396 Mon Sep 17 00:00:00 2001 From: Garry Newman Date: Sun, 14 Apr 2019 21:57:09 +0100 Subject: [PATCH] Music --- .../Generated/Interfaces/ISteamMusic.cs | 129 +++ Facepunch.Steamworks/Redux/Music.cs | 82 ++ .../SteamNative/SteamNative.Structs.cs | 26 + Generator/CodeWriter/CodeWriter.cs | 1 + Generator/steam_api_missing.json | 753 +++++++++--------- 5 files changed, 618 insertions(+), 373 deletions(-) create mode 100644 Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs create mode 100644 Facepunch.Steamworks/Redux/Music.cs diff --git a/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs new file mode 100644 index 0000000..6fe961f --- /dev/null +++ b/Facepunch.Steamworks/Generated/Interfaces/ISteamMusic.cs @@ -0,0 +1,129 @@ +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using SteamNative; + + +namespace Steamworks.Internal +{ + public class ISteamMusic : BaseSteamInterface + { + public override string InterfaceName => "STEAMMUSIC_INTERFACE_VERSION001"; + + public override void InitInternals() + { + BIsEnabledDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 0) ); + BIsPlayingDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 8) ); + GetPlaybackStatusDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 16) ); + PlayDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 24) ); + PauseDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 32) ); + PlayPreviousDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 40) ); + PlayNextDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 48) ); + SetVolumeDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 56) ); + GetVolumeDelegatePointer = Marshal.GetDelegateForFunctionPointer( Marshal.ReadIntPtr( VTable, 64) ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + [return: MarshalAs( UnmanagedType.I1 )] + public delegate bool BIsEnabledDelegate( IntPtr self ); + private BIsEnabledDelegate BIsEnabledDelegatePointer; + + #endregion + public bool BIsEnabled() + { + return BIsEnabledDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + [return: MarshalAs( UnmanagedType.I1 )] + public delegate bool BIsPlayingDelegate( IntPtr self ); + private BIsPlayingDelegate BIsPlayingDelegatePointer; + + #endregion + public bool BIsPlaying() + { + return BIsPlayingDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate AudioPlayback_Status GetPlaybackStatusDelegate( IntPtr self ); + private GetPlaybackStatusDelegate GetPlaybackStatusDelegatePointer; + + #endregion + public AudioPlayback_Status GetPlaybackStatus() + { + return GetPlaybackStatusDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate void PlayDelegate( IntPtr self ); + private PlayDelegate PlayDelegatePointer; + + #endregion + public void Play() + { + PlayDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate void PauseDelegate( IntPtr self ); + private PauseDelegate PauseDelegatePointer; + + #endregion + public void Pause() + { + PauseDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate void PlayPreviousDelegate( IntPtr self ); + private PlayPreviousDelegate PlayPreviousDelegatePointer; + + #endregion + public void PlayPrevious() + { + PlayPreviousDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate void PlayNextDelegate( IntPtr self ); + private PlayNextDelegate PlayNextDelegatePointer; + + #endregion + public void PlayNext() + { + PlayNextDelegatePointer( Self ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate void SetVolumeDelegate( IntPtr self, float flVolume ); + private SetVolumeDelegate SetVolumeDelegatePointer; + + #endregion + public void SetVolume( float flVolume ) + { + SetVolumeDelegatePointer( Self, flVolume ); + } + + #region FunctionMeta + [UnmanagedFunctionPointer( CallingConvention.ThisCall )] + public delegate float GetVolumeDelegate( IntPtr self ); + private GetVolumeDelegate GetVolumeDelegatePointer; + + #endregion + public float GetVolume() + { + return GetVolumeDelegatePointer( Self ); + } + + } +} diff --git a/Facepunch.Steamworks/Redux/Music.cs b/Facepunch.Steamworks/Redux/Music.cs new file mode 100644 index 0000000..b97935e --- /dev/null +++ b/Facepunch.Steamworks/Redux/Music.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using SteamNative; + +namespace Steamworks +{ + /// + /// Undocumented Parental Settings + /// + public static class Music + { + static Internal.ISteamMusic _internal; + internal static Internal.ISteamMusic music + { + get + { + if ( _internal == null ) + _internal = new Internal.ISteamMusic(); + + return _internal; + } + } + + internal static void InstallEvents() + { + new Event( x => OnPlaybackChanged?.Invoke() ); + new Event( x => OnVolumeChanged?.Invoke( x.NewVolume ) ); + } + + /// + /// Playback status changed + /// + public static event Action OnPlaybackChanged; + + /// + /// Volume changed, parameter is new volume + /// + public static event Action OnVolumeChanged; + + /// + /// Checks if Steam Music is enabled + /// + public static bool IsEnabled => music.BIsEnabled(); + + /// + /// true if a song is currently playing, paused, or queued up to play; otherwise false. + /// + public static bool IsPlaying => music.BIsPlaying(); + + /// + /// Gets the current status of the Steam Music player + /// + public static AudioPlayback_Status Status => music.GetPlaybackStatus(); + + + public static void Play() => music.Play(); + + public static void Pause() => music.Pause(); + + /// + /// Have the Steam Music player play the previous song. + /// + public static void PlayPrevious() => music.PlayPrevious(); + + /// + /// Have the Steam Music player skip to the next song + /// + public static void PlayNext() => music.PlayNext(); + + /// + /// Gets/Sets the current volume of the Steam Music player + /// + public static float Volume + { + get => music.GetVolume(); + set => music.SetVolume( value ); + } + } +} \ No newline at end of file diff --git a/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs b/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs index 819c61d..a079f0a 100644 --- a/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs +++ b/Facepunch.Steamworks/SteamNative/SteamNative.Structs.cs @@ -6816,6 +6816,31 @@ public struct Pack8 #endregion } + public struct PlaybackStatusHasChanged_t : Steamworks.ISteamCallback + { + + #region ISteamCallback + public int GetCallbackId() => CallbackIdentifiers.SteamMusic + 1; + public int GetStructSize() => System.Runtime.InteropServices.Marshal.SizeOf( Platform.PackSmall ? typeof(Pack4) : typeof(Pack8) ); + public Steamworks.ISteamCallback Fill( IntPtr p ) => Platform.PackSmall ? ((PlaybackStatusHasChanged_t)(Pack4) Marshal.PtrToStructure( p, typeof(Pack4) )) : ((PlaybackStatusHasChanged_t)(Pack8) Marshal.PtrToStructure( p, typeof(Pack8) )); + #endregion + #region Packed Versions + [StructLayout( LayoutKind.Sequential, Pack = 4 )] + public struct Pack4 + { + + public static implicit operator PlaybackStatusHasChanged_t ( PlaybackStatusHasChanged_t.Pack4 d ) => new PlaybackStatusHasChanged_t{ }; + } + + [StructLayout( LayoutKind.Sequential, Pack = 8 )] + public struct Pack8 + { + + public static implicit operator PlaybackStatusHasChanged_t ( PlaybackStatusHasChanged_t.Pack8 d ) => new PlaybackStatusHasChanged_t{ }; + } + #endregion + } + public struct NewUrlLaunchParameters_t : Steamworks.ISteamCallback { @@ -7458,6 +7483,7 @@ internal static void RegisterCallbacks( Facepunch.Steamworks.BaseSteamworks stea new CallbackHandle( steamworks ); new CallbackHandle( steamworks ); new CallbackHandle( steamworks ); + new CallbackHandle( steamworks ); new CallbackHandle( steamworks ); new CallbackHandle( steamworks ); new CallbackHandle( steamworks ); diff --git a/Generator/CodeWriter/CodeWriter.cs b/Generator/CodeWriter/CodeWriter.cs index 61a3a89..db12e2e 100644 --- a/Generator/CodeWriter/CodeWriter.cs +++ b/Generator/CodeWriter/CodeWriter.cs @@ -95,6 +95,7 @@ public void ToFolder( string folder ) GenerateVTableClass( "ISteamApps", $"{folder}../Generated/Interfaces/ISteamApps.cs" ); GenerateVTableClass( "ISteamUtils", $"{folder}../Generated/Interfaces/ISteamUtils.cs" ); GenerateVTableClass( "ISteamParentalSettings", $"{folder}../Generated/Interfaces/ISteamParentalSettings.cs" ); + GenerateVTableClass( "ISteamMusic", $"{folder}../Generated/Interfaces/ISteamMusic.cs" ); } } diff --git a/Generator/steam_api_missing.json b/Generator/steam_api_missing.json index 7216000..e1e9189 100644 --- a/Generator/steam_api_missing.json +++ b/Generator/steam_api_missing.json @@ -1,374 +1,381 @@ { - "structs": [ - { - "struct": "NewUrlLaunchParameters_t", - "fields": [ - ] - }, - - { - "struct": "ItemInstalled_t", - "fields": [ - { - "fieldname": "m_unAppID", - "fieldtype": "AppId_t" - }, - { - "fieldname": "m_nPublishedFileId", - "fieldtype": "PublishedFileId_t" - } - ] - }, - - { - "struct": "InputAnalogActionData_t", - "fields": [ - { - "fieldname": "eMode", - "fieldtype": "EInputSourceMode" - }, - { - "fieldname": "x", - "fieldtype": "float" - }, - { - "fieldname": "y", - "fieldtype": "float" - }, - { - "fieldname": "bActive", - "fieldtype": "bool" - } - ] - }, - - { - "struct": "InputMotionData_t", - "fields": [ - { - "fieldname": "rotQuatX", - "fieldtype": "float" - }, - - { - "fieldname": "rotQuatY", - "fieldtype": "float" - }, - - { - "fieldname": "rotQuatZ", - "fieldtype": "float" - }, - - { - "fieldname": "rotQuatW", - "fieldtype": "float" - }, - - { - "fieldname": "posAccelX", - "fieldtype": "float" - }, - - { - "fieldname": "posAccelY", - "fieldtype": "float" - }, - - { - "fieldname": "posAccelZ", - "fieldtype": "float" - }, - - { - "fieldname": "rotVelX", - "fieldtype": "float" - }, - - { - "fieldname": "rotVelY", - "fieldtype": "float" - }, - - { - "fieldname": "rotVelZ", - "fieldtype": "float" - } - - ] - }, - - { - "struct": "InputDigitalActionData_t", - "fields": [ - { - "fieldname": "bState", - "fieldtype": "bool" - }, - { - "fieldname": "bActive", - "fieldtype": "bool" - } - ] - }, - - { - "struct": "SteamInventoryDefinitionUpdate_t" - }, - - { - "struct": "SteamParentalSettingsChanged_t" - }, - - { - "struct": "SteamServersConnected_t" - }, - { - "struct": "NewLaunchQueryParameters_t" - }, - - { - "struct": "GCMessageAvailable_t", - "fields": [ - { - "fieldname": "m_nMessageSize", - "fieldtype": "uint32" - } - ] - }, - { - "struct": "GCMessageFailed_t" - }, - { - "struct": "ScreenshotRequested_t" - }, - { - "struct": "LicensesUpdated_t" - }, - { - "struct": "SteamShutdown_t" - }, - { - "struct": "IPCountry_t" - }, - { - "struct": "IPCFailure_t", - "fields": [ - { - "fieldname": "m_eFailureType", - "fieldtype": "uint8" - } - ] - } - ], - - "methods": - [ - { - "classname": "SteamApi", - "methodname": "SteamAPI_Init", - "returntype": "bool", - "NeedsSelfPointer": false - }, - - { - "classname": "SteamApi", - "methodname": "SteamAPI_RunCallbacks", - "returntype": "void", - "NeedsSelfPointer": false - }, - - - { - "classname": "SteamApi", - "methodname": "SteamGameServer_RunCallbacks", - "returntype": "void", - "NeedsSelfPointer": false - }, - - - { - "classname": "SteamApi", - "methodname": "SteamAPI_RegisterCallback", - "returntype": "void", - "NeedsSelfPointer": false, - "params": - [ - { - "paramname": "pCallback", - "paramtype": "void *" - }, - - { - "paramname": "callback", - "paramtype": "int" - } - ] - }, - - - { - "classname": "SteamApi", - "methodname": "SteamAPI_UnregisterCallback", - "returntype": "void", - "NeedsSelfPointer": false, - "params": - [ - { - "paramname": "pCallback", - "paramtype": "void *" - } - ] - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_RegisterCallResult", - "returntype": "void", - "params": - [ - { - "paramname": "pCallback", - "paramtype": "void *" - }, - { - "paramname": "callback", - "paramtype": "SteamAPICall_t" - } - ] - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_UnregisterCallResult", - "returntype": "void", - "params": - [ - { - "paramname": "pCallback", - "paramtype": "void *" - }, - { - "paramname": "callback", - "paramtype": "SteamAPICall_t" - } - ] - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamInternal_GameServer_Init", - "returntype": "bool", - "params": - [ - { - "paramname": "unIP", - "paramtype": "uint32" - }, - { - "paramname": "usPort", - "paramtype": "uint16" - }, - { - "paramname": "usGamePort", - "paramtype": "uint16" - }, - { - "paramname": "usQueryPort", - "paramtype": "uint16" - }, - { - "paramname": "eServerMode", - "paramtype": "int" - }, - { - "paramname": "pchVersionString", - "paramtype": "const char *" - } - ] - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_Shutdown", - "returntype": "void" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamGameServer_Shutdown", - "returntype": "void" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_GetHSteamUser", - "returntype": "HSteamUser" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_GetHSteamPipe", - "returntype": "HSteamPipe" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamGameServer_GetHSteamUser", - "returntype": "HSteamUser" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamGameServer_GetHSteamPipe", - "returntype": "HSteamPipe" - }, - - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamInternal_CreateInterface", - "returntype": "void *", - "params": - [ - { - "paramname": "version", - "paramtype": "const char *" - } - ] - }, - - { - "NeedsSelfPointer": false, - "classname": "SteamApi", - "methodname": "SteamAPI_RestartAppIfNecessary", - "returntype": "bool", - "params": - [ - { - "paramname": "unOwnAppID", - "paramtype": "uint32" - } - ] - } - ] -} \ No newline at end of file + "structs": [ + + + + { + "struct": "PlaybackStatusHasChanged_t", + "fields": [ ] + }, + + { + "struct": "NewUrlLaunchParameters_t", + "fields": [ ] + }, + + { + "struct": "ItemInstalled_t", + "fields": [ + { + "fieldname": "m_unAppID", + "fieldtype": "AppId_t" + }, + { + "fieldname": "m_nPublishedFileId", + "fieldtype": "PublishedFileId_t" + } + ] + }, + + { + "struct": "InputAnalogActionData_t", + "fields": [ + { + "fieldname": "eMode", + "fieldtype": "EInputSourceMode" + }, + { + "fieldname": "x", + "fieldtype": "float" + }, + { + "fieldname": "y", + "fieldtype": "float" + }, + { + "fieldname": "bActive", + "fieldtype": "bool" + } + ] + }, + + { + "struct": "InputMotionData_t", + "fields": [ + { + "fieldname": "rotQuatX", + "fieldtype": "float" + }, + + { + "fieldname": "rotQuatY", + "fieldtype": "float" + }, + + { + "fieldname": "rotQuatZ", + "fieldtype": "float" + }, + + { + "fieldname": "rotQuatW", + "fieldtype": "float" + }, + + { + "fieldname": "posAccelX", + "fieldtype": "float" + }, + + { + "fieldname": "posAccelY", + "fieldtype": "float" + }, + + { + "fieldname": "posAccelZ", + "fieldtype": "float" + }, + + { + "fieldname": "rotVelX", + "fieldtype": "float" + }, + + { + "fieldname": "rotVelY", + "fieldtype": "float" + }, + + { + "fieldname": "rotVelZ", + "fieldtype": "float" + } + + ] + }, + + { + "struct": "InputDigitalActionData_t", + "fields": [ + { + "fieldname": "bState", + "fieldtype": "bool" + }, + { + "fieldname": "bActive", + "fieldtype": "bool" + } + ] + }, + + { + "struct": "SteamInventoryDefinitionUpdate_t" + }, + + { + "struct": "SteamParentalSettingsChanged_t" + }, + + { + "struct": "SteamServersConnected_t" + }, + { + "struct": "NewLaunchQueryParameters_t" + }, + + { + "struct": "GCMessageAvailable_t", + "fields": [ + { + "fieldname": "m_nMessageSize", + "fieldtype": "uint32" + } + ] + }, + { + "struct": "GCMessageFailed_t" + }, + { + "struct": "ScreenshotRequested_t" + }, + { + "struct": "LicensesUpdated_t" + }, + { + "struct": "SteamShutdown_t" + }, + { + "struct": "IPCountry_t" + }, + { + "struct": "IPCFailure_t", + "fields": [ + { + "fieldname": "m_eFailureType", + "fieldtype": "uint8" + } + ] + } + ], + + "methods": + [ + { + "classname": "SteamApi", + "methodname": "SteamAPI_Init", + "returntype": "bool", + "NeedsSelfPointer": false + }, + + { + "classname": "SteamApi", + "methodname": "SteamAPI_RunCallbacks", + "returntype": "void", + "NeedsSelfPointer": false + }, + + + { + "classname": "SteamApi", + "methodname": "SteamGameServer_RunCallbacks", + "returntype": "void", + "NeedsSelfPointer": false + }, + + + { + "classname": "SteamApi", + "methodname": "SteamAPI_RegisterCallback", + "returntype": "void", + "NeedsSelfPointer": false, + "params": + [ + { + "paramname": "pCallback", + "paramtype": "void *" + }, + + { + "paramname": "callback", + "paramtype": "int" + } + ] + }, + + + { + "classname": "SteamApi", + "methodname": "SteamAPI_UnregisterCallback", + "returntype": "void", + "NeedsSelfPointer": false, + "params": + [ + { + "paramname": "pCallback", + "paramtype": "void *" + } + ] + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_RegisterCallResult", + "returntype": "void", + "params": + [ + { + "paramname": "pCallback", + "paramtype": "void *" + }, + { + "paramname": "callback", + "paramtype": "SteamAPICall_t" + } + ] + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_UnregisterCallResult", + "returntype": "void", + "params": + [ + { + "paramname": "pCallback", + "paramtype": "void *" + }, + { + "paramname": "callback", + "paramtype": "SteamAPICall_t" + } + ] + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamInternal_GameServer_Init", + "returntype": "bool", + "params": + [ + { + "paramname": "unIP", + "paramtype": "uint32" + }, + { + "paramname": "usPort", + "paramtype": "uint16" + }, + { + "paramname": "usGamePort", + "paramtype": "uint16" + }, + { + "paramname": "usQueryPort", + "paramtype": "uint16" + }, + { + "paramname": "eServerMode", + "paramtype": "int" + }, + { + "paramname": "pchVersionString", + "paramtype": "const char *" + } + ] + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_Shutdown", + "returntype": "void" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamGameServer_Shutdown", + "returntype": "void" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_GetHSteamUser", + "returntype": "HSteamUser" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_GetHSteamPipe", + "returntype": "HSteamPipe" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamGameServer_GetHSteamUser", + "returntype": "HSteamUser" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamGameServer_GetHSteamPipe", + "returntype": "HSteamPipe" + }, + + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamInternal_CreateInterface", + "returntype": "void *", + "params": + [ + { + "paramname": "version", + "paramtype": "const char *" + } + ] + }, + + { + "NeedsSelfPointer": false, + "classname": "SteamApi", + "methodname": "SteamAPI_RestartAppIfNecessary", + "returntype": "bool", + "params": + [ + { + "paramname": "unOwnAppID", + "paramtype": "uint32" + } + ] + } + ] + } \ No newline at end of file