get achievements working again
[fishladder.git] / vg / vg_steamworks.h
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5bc04f221b31ee2e639c93327d867ef944ea689a 100644 (file)
@@ -0,0 +1,278 @@
+#if defined(__linux__) || defined(__APPLE__) 
+// The 32-bit version of gcc has the alignment requirement for uint64 and double set to
+// 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
+// The 64-bit version of gcc has the alignment requirement for these types set to
+// 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
+// The 64-bit structure packing has to match the 32-bit structure packing for each platform.
+ #define VALVE_CALLBACK_PACK_SMALL
+#else
+ #define VALVE_CALLBACK_PACK_LARGE
+#endif
+
+#if defined( VALVE_CALLBACK_PACK_SMALL )
+ #pragma pack( push, 4 )
+#elif defined( VALVE_CALLBACK_PACK_LARGE )
+ #pragma pack( push, 8 )
+#else
+ #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
+#endif 
+
+// Types
+typedef void ISteamFriends;
+typedef void ISteamUserStats;
+typedef void ISteamUtils;
+typedef void ISteamUser;
+typedef void ISteamNetworking;
+
+typedef i32    HSteamPipe;
+typedef i32    HSteamUser;
+
+typedef int E_iCallBack_t;
+
+typedef u32 SNetSocket_t;                      // CreateP2PConnectionSocket()
+typedef u32 SNetListenSocket_t;        // CreateListenSocket()
+
+typedef u64    uint64_steamid;
+typedef u64 SteamAPICall_t;
+
+enum { k_iSteamUserCallbacks = 100 };
+enum { k_iSteamGameServerCallbacks = 200 };
+enum { k_iSteamFriendsCallbacks = 300 };
+enum { k_iSteamBillingCallbacks = 400 };
+enum { k_iSteamMatchmakingCallbacks = 500 };
+enum { k_iSteamContentServerCallbacks = 600 };
+enum { k_iSteamUtilsCallbacks = 700 };
+enum { k_iClientFriendsCallbacks = 800 };
+enum { k_iClientUserCallbacks = 900 };
+enum { k_iSteamAppsCallbacks = 1000 };
+enum { k_iSteamUserStatsCallbacks = 1100 };
+enum { k_iSteamNetworkingCallbacks = 1200 };
+enum { k_iSteamNetworkingSocketsCallbacks = 1220 };
+enum { k_iSteamNetworkingMessagesCallbacks = 1250 };
+enum { k_iSteamNetworkingUtilsCallbacks = 1280 };
+enum { k_iClientRemoteStorageCallbacks = 1300 };
+enum { k_iClientDepotBuilderCallbacks = 1400 };
+enum { k_iSteamGameServerItemsCallbacks = 1500 };
+enum { k_iClientUtilsCallbacks = 1600 };
+enum { k_iSteamGameCoordinatorCallbacks = 1700 };
+enum { k_iSteamGameServerStatsCallbacks = 1800 };
+enum { k_iSteam2AsyncCallbacks = 1900 };
+enum { k_iSteamGameStatsCallbacks = 2000 };
+enum { k_iClientHTTPCallbacks = 2100 };
+enum { k_iClientScreenshotsCallbacks = 2200 };
+enum { k_iSteamScreenshotsCallbacks = 2300 };
+enum { k_iClientAudioCallbacks = 2400 };
+enum { k_iClientUnifiedMessagesCallbacks = 2500 };
+enum { k_iSteamStreamLauncherCallbacks = 2600 };
+enum { k_iClientControllerCallbacks = 2700 };
+enum { k_iSteamControllerCallbacks = 2800 };
+enum { k_iClientParentalSettingsCallbacks = 2900 };
+enum { k_iClientDeviceAuthCallbacks = 3000 };
+enum { k_iClientNetworkDeviceManagerCallbacks = 3100 };
+enum { k_iClientMusicCallbacks = 3200 };
+enum { k_iClientRemoteClientManagerCallbacks = 3300 };
+enum { k_iClientUGCCallbacks = 3400 };
+enum { k_iSteamStreamClientCallbacks = 3500 };
+enum { k_IClientProductBuilderCallbacks = 3600 };
+enum { k_iClientShortcutsCallbacks = 3700 };
+enum { k_iClientRemoteControlManagerCallbacks = 3800 };
+enum { k_iSteamAppListCallbacks = 3900 };
+enum { k_iSteamMusicCallbacks = 4000 };
+enum { k_iSteamMusicRemoteCallbacks = 4100 };
+enum { k_iClientVRCallbacks = 4200 };
+enum { k_iClientGameNotificationCallbacks = 4300 }; 
+enum { k_iSteamGameNotificationCallbacks = 4400 }; 
+enum { k_iSteamHTMLSurfaceCallbacks = 4500 };
+enum { k_iClientVideoCallbacks = 4600 };
+enum { k_iClientInventoryCallbacks = 4700 };
+enum { k_iClientBluetoothManagerCallbacks = 4800 };
+enum { k_iClientSharedConnectionCallbacks = 4900 };
+enum { k_ISteamParentalSettingsCallbacks = 5000 };
+enum { k_iClientShaderCallbacks = 5100 };
+enum { k_iSteamGameSearchCallbacks = 5200 };
+enum { k_iSteamPartiesCallbacks = 5300 };
+enum { k_iClientPartiesCallbacks = 5400 };
+enum { k_iSteamSTARCallbacks = 5500 };
+enum { k_iClientSTARCallbacks = 5600 };
+enum { k_iSteamRemotePlayCallbacks = 5700 };
+enum { k_iClientCompatCallbacks = 5800 };
+enum { k_iSteamChatCallbacks = 5900 };
+
+// Structures
+typedef struct {  
+        u32 m_u32;
+    u64 m_u64;
+    u16 m_u16;
+    double m_d;
+} ValvePackingSentinel_t;
+
+typedef struct {
+
+       HSteamUser m_hSteamUser;        // Specific user to whom this callback applies.
+       int m_iCallback;                                // Callback identifier.  (Corresponds to the k_iCallback enum in the callback structure.)
+       uint8_t *m_pubParam;            // Points to the callback structure
+       int m_cubParam;                                 // Size of the data pointed to by m_pubParam
+       
+} CallbackMsg_t;
+
+typedef struct {
+
+       SteamAPICall_t m_hAsyncCall;
+       int m_iCallback;
+       u32 m_cubParam;
+       
+} SteamAPICallCompleted_t;
+#define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
+
+
+#pragma pack( pop )
+
+// API
+void           SteamAPI_Shutdown();
+int            SteamAPI_Init();
+int            SteamAPI_RestartAppIfNecessary( u32 unOwnAppID );
+
+void           SteamAPI_ManualDispatch_Init();
+void           SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
+int            SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg );
+void           SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
+int            SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, int *pbFailed );
+void           SteamAPI_ReleaseCurrentThreadMemory();
+
+int            SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const char *pchName );
+
+HSteamPipe SteamAPI_GetHSteamPipe();
+HSteamUser SteamAPI_GetHSteamUser();
+
+struct
+{
+       ISteamFriends           *friends;
+       ISteamUser                      *user;
+       ISteamUserStats         *stats;
+       ISteamNetworking        *net;
+       
+       HSteamPipe                      pipe;
+} steam_api_classes;
+
+ISteamFriends          *SteamAPI_SteamFriends_v017();
+ISteamUser                     *SteamAPI_SteamUser_v021();
+ISteamUserStats        *SteamAPI_SteamUserStats_v012();
+ISteamNetworking       *SteamAPI_SteamNetworking_v006();
+
+static void sw_exit(void)
+{
+       SteamAPI_Shutdown();
+}
+
+static int sw_init(void)
+{
+       #if defined(VALVE_CALLBACK_PACK_SMALL)
+       if( sizeof(ValvePackingSentinel_t) != 24 ){
+               printf( "Struct packing error: ValvePackingSentinel_t expected 24 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
+               return 0;
+       }
+       #else
+               if( sizeof(ValvePackingSentinel_t) != 32 ){
+                       printf( "Struct packing error: ValvePackingSentinel_t expected 32 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
+                       return 0;
+               }
+       #endif
+       
+       vg_info( "Intializing steamworks\n" );
+       
+       if( SteamAPI_RestartAppIfNecessary( VG_STEAM_APPID ) == 1 )
+       {
+               vg_info( "Restarting app via steam\n" );
+               return 0;
+       }
+       
+       if( !SteamAPI_Init() )
+       {
+               vg_error( "Steamworks connection failed\n" );
+               return 0;
+       }
+       
+       SteamAPI_ManualDispatch_Init();
+       
+       steam_api_classes.friends = SteamAPI_SteamFriends_v017();
+       steam_api_classes.user = SteamAPI_SteamUser_v021();
+       steam_api_classes.stats = SteamAPI_SteamUserStats_v012();
+       steam_api_classes.net = SteamAPI_SteamNetworking_v006();
+       
+       if( !steam_api_classes.friends || !steam_api_classes.user || !steam_api_classes.stats || !steam_api_classes.net )
+       {
+               vg_error( "Steamworks interface pointers failed. Steamworks DLL may be old\n" );
+               SteamAPI_Shutdown();
+               return 0;
+       }
+       
+       steam_api_classes.pipe = SteamAPI_GetHSteamPipe();
+       vg_success( "Steamworks API running\n" );
+       
+       vg_register_exit( &sw_exit, "SteamAPI" );
+       return 1;
+}
+
+static void sw_event_loop(void)
+{
+       SteamAPI_ManualDispatch_RunFrame( steam_api_classes.pipe );
+       CallbackMsg_t callback;
+       
+       while( SteamAPI_ManualDispatch_GetNextCallback( steam_api_classes.pipe, &callback ) )
+       {
+               // Check for dispatching API call results
+               if( callback.m_iCallback == SW_CBID_SteamAPICallCompleted ){
+               
+                       SteamAPICallCompleted_t *pCallCompleted = (SteamAPICallCompleted_t *)&callback;
+                       void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
+                       int bFailed;
+                       
+                       if( SteamAPI_ManualDispatch_GetAPICallResult( 
+                               steam_api_classes.pipe, 
+                               pCallCompleted->m_hAsyncCall, 
+                               pTmpCallResult,
+                               pCallCompleted->m_cubParam, 
+                               pCallCompleted->m_iCallback, 
+                               &bFailed ) 
+                       )
+                       {
+                               // Dispatch the call result to the registered handler(s) for the
+                               // call identified by pCallCompleted->m_hAsyncCall
+                       }
+                       
+                       free( pTmpCallResult );
+               } 
+               else 
+               {
+                       // Look at callback.m_iCallback to see what kind of callback it is,
+                       // and dispatch to appropriate handler(s)
+                       
+                       vg_info( "steamworks_event::callback( %i )\n", callback.m_iCallback );
+                       
+                       //void *data = callback.m_pubParam;
+                       
+                       switch( callback.m_iCallback )
+                       {
+                               default: break;
+                       }
+               }
+               
+               SteamAPI_ManualDispatch_FreeLastCallback( steam_api_classes.pipe );
+       }
+}
+
+static void sw_set_achievement( const char *vg_ach_name )
+{
+       struct vg_achievement *ach = NULL;
+       
+       for( int i = 0; i < vg_list_size( vg_achievements ); i ++ )
+               if( !strcmp( vg_ach_name, vg_achievements[i].name ) )
+                       ach = &vg_achievements[i];
+       
+       if( !ach->is_set )
+       {
+               SteamAPI_ISteamUserStats_SetAchievement( steam_api_classes.stats, vg_ach_name );
+               ach->is_set = 1;
+               vg_success( "Achievement set: '%s'\n", vg_ach_name );
+       }
+}