X-Git-Url: https://harrygodden.com/git/?a=blobdiff_plain;f=vg%2Fvg_steamworks.h;h=5bc04f221b31ee2e639c93327d867ef944ea689a;hb=499bcabb125cdf2618a6be89ccade08b007254f3;hp=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391;hpb=5276db4a15a6565813bdde22198f8aee4030e56f;p=fishladder.git diff --git a/vg/vg_steamworks.h b/vg/vg_steamworks.h index e69de29..5bc04f2 100644 --- a/vg/vg_steamworks.h +++ b/vg/vg_steamworks.h @@ -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 ); + } +}