2 steamworks_thin.h - simple wrapper / macro set for building steamworks apps in pure C
4 Put the latest steam_api.dll in your build folder
5 link against -lsteam_api
7 all functions are prefixed with sw_
16 GLuint _localplayer_image
;
17 char _localplayer_name
[128];
21 #ifndef VOYAGER_RELEASE_MODE
22 #define STRUCTURE_PACK_CHECK
25 /*______________________________________________________________________________________________________________________________
28 ______________________________________________________________________________________________________________________________*/
32 k_ESteamIPTypeIPv4
= 0,
33 k_ESteamIPTypeIPv6
= 1,
39 k_ESNetSocketConnectionTypeNotConnected
= 0,
40 k_ESNetSocketConnectionTypeUDP
= 1,
41 k_ESNetSocketConnectionTypeUDPRelay
= 2,
43 } ESNetSocketConnectionType_t
;
45 //-----------------------------------------------------------------------------
46 // Purpose: Base values for callback identifiers, each callback must
48 //-----------------------------------------------------------------------------
50 enum { k_iSteamUserCallbacks
= 100 };
51 enum { k_iSteamGameServerCallbacks
= 200 };
52 enum { k_iSteamFriendsCallbacks
= 300 };
53 enum { k_iSteamBillingCallbacks
= 400 };
54 enum { k_iSteamMatchmakingCallbacks
= 500 };
55 enum { k_iSteamContentServerCallbacks
= 600 };
56 enum { k_iSteamUtilsCallbacks
= 700 };
57 enum { k_iClientFriendsCallbacks
= 800 };
58 enum { k_iClientUserCallbacks
= 900 };
59 enum { k_iSteamAppsCallbacks
= 1000 };
60 enum { k_iSteamUserStatsCallbacks
= 1100 };
61 enum { k_iSteamNetworkingCallbacks
= 1200 };
62 enum { k_iSteamNetworkingSocketsCallbacks
= 1220 };
63 enum { k_iSteamNetworkingMessagesCallbacks
= 1250 };
64 enum { k_iSteamNetworkingUtilsCallbacks
= 1280 };
65 enum { k_iClientRemoteStorageCallbacks
= 1300 };
66 enum { k_iClientDepotBuilderCallbacks
= 1400 };
67 enum { k_iSteamGameServerItemsCallbacks
= 1500 };
68 enum { k_iClientUtilsCallbacks
= 1600 };
69 enum { k_iSteamGameCoordinatorCallbacks
= 1700 };
70 enum { k_iSteamGameServerStatsCallbacks
= 1800 };
71 enum { k_iSteam2AsyncCallbacks
= 1900 };
72 enum { k_iSteamGameStatsCallbacks
= 2000 };
73 enum { k_iClientHTTPCallbacks
= 2100 };
74 enum { k_iClientScreenshotsCallbacks
= 2200 };
75 enum { k_iSteamScreenshotsCallbacks
= 2300 };
76 enum { k_iClientAudioCallbacks
= 2400 };
77 enum { k_iClientUnifiedMessagesCallbacks
= 2500 };
78 enum { k_iSteamStreamLauncherCallbacks
= 2600 };
79 enum { k_iClientControllerCallbacks
= 2700 };
80 enum { k_iSteamControllerCallbacks
= 2800 };
81 enum { k_iClientParentalSettingsCallbacks
= 2900 };
82 enum { k_iClientDeviceAuthCallbacks
= 3000 };
83 enum { k_iClientNetworkDeviceManagerCallbacks
= 3100 };
84 enum { k_iClientMusicCallbacks
= 3200 };
85 enum { k_iClientRemoteClientManagerCallbacks
= 3300 };
86 enum { k_iClientUGCCallbacks
= 3400 };
87 enum { k_iSteamStreamClientCallbacks
= 3500 };
88 enum { k_IClientProductBuilderCallbacks
= 3600 };
89 enum { k_iClientShortcutsCallbacks
= 3700 };
90 enum { k_iClientRemoteControlManagerCallbacks
= 3800 };
91 enum { k_iSteamAppListCallbacks
= 3900 };
92 enum { k_iSteamMusicCallbacks
= 4000 };
93 enum { k_iSteamMusicRemoteCallbacks
= 4100 };
94 enum { k_iClientVRCallbacks
= 4200 };
95 enum { k_iClientGameNotificationCallbacks
= 4300 };
96 enum { k_iSteamGameNotificationCallbacks
= 4400 };
97 enum { k_iSteamHTMLSurfaceCallbacks
= 4500 };
98 enum { k_iClientVideoCallbacks
= 4600 };
99 enum { k_iClientInventoryCallbacks
= 4700 };
100 enum { k_iClientBluetoothManagerCallbacks
= 4800 };
101 enum { k_iClientSharedConnectionCallbacks
= 4900 };
102 enum { k_ISteamParentalSettingsCallbacks
= 5000 };
103 enum { k_iClientShaderCallbacks
= 5100 };
104 enum { k_iSteamGameSearchCallbacks
= 5200 };
105 enum { k_iSteamPartiesCallbacks
= 5300 };
106 enum { k_iClientPartiesCallbacks
= 5400 };
107 enum { k_iSteamSTARCallbacks
= 5500 };
108 enum { k_iClientSTARCallbacks
= 5600 };
109 enum { k_iSteamRemotePlayCallbacks
= 5700 };
110 enum { k_iClientCompatCallbacks
= 5800 };
111 enum { k_iSteamChatCallbacks
= 5900 };
113 // Steam universes. Each universe is a self-contained Steam instance.
115 k_EUniverseInvalid
= 0,
116 k_EUniversePublic
= 1,
118 k_EUniverseInternal
= 3,
120 // k_EUniverseRC = 5, // no such universe anymore
125 // Basic UDP send. Packets can't be bigger than 1200 bytes (your typical MTU size). Can be lost, or arrive out of order (rare).
126 // The sending API does have some knowledge of the underlying connection, so if there is no NAT-traversal accomplished or
127 // there is a recognized adjustment happening on the connection, the packet will be batched until the connection is open again.
128 k_EP2PSendUnreliable
= 0,
130 // As above, but if the underlying p2p connection isn't yet established the packet will just be thrown away. Using this on the first
131 // packet sent to a remote host almost guarantees the packet will be dropped.
132 // This is only really useful for kinds of data that should never buffer up, i.e. voice payload packets
133 k_EP2PSendUnreliableNoDelay
= 1,
135 // Reliable message send. Can send up to 1MB of data in a single message.
136 // Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for efficient sends of large chunks of data.
137 k_EP2PSendReliable
= 2,
139 // As above, but applies the Nagle algorithm to the send - sends will accumulate
140 // until the current MTU size (typically ~1200 bytes, but can change) or ~200ms has passed (Nagle algorithm).
141 // Useful if you want to send a set of smaller messages but have the coalesced into a single packet
142 // Since the reliable stream is all ordered, you can do several small message sends with k_EP2PSendReliableWithBuffering and then
143 // do a normal k_EP2PSendReliable to force all the buffered data to be sent.
144 k_EP2PSendReliableWithBuffering
= 3,
148 // list of possible errors returned by SendP2PPacket() API
149 // these will be posted in the P2PSessionConnectFail_t callback
151 k_EP2PSessionErrorNone
= 0,
152 k_EP2PSessionErrorNotRunningApp
= 1, // target is not running the same game
153 k_EP2PSessionErrorNoRightsToApp
= 2, // local user doesn't own the app that is running
154 k_EP2PSessionErrorDestinationNotLoggedIn
= 3, // target user isn't connected to Steam
155 k_EP2PSessionErrorTimeout
= 4, // target isn't responding, perhaps not calling AcceptP2PSessionWithUser()
156 // corporate firewalls can also block this (NAT traversal is not firewall traversal)
157 // make sure that UDP ports 3478, 4379, and 4380 are open in an outbound direction
158 k_EP2PSessionErrorMax
= 5
159 } EP2PSessionError_t
;
163 k_EFriendFlagNone
= 0x00,
164 k_EFriendFlagBlocked
= 0x01,
165 k_EFriendFlagFriendshipRequested
= 0x02,
166 k_EFriendFlagImmediate
= 0x04, // "regular" friend
167 k_EFriendFlagClanMember
= 0x08,
168 k_EFriendFlagOnGameServer
= 0x10,
169 // k_EFriendFlagHasPlayedWith = 0x20, // not currently used
170 // k_EFriendFlagFriendOfFriend = 0x40, // not currently used
171 k_EFriendFlagRequestingFriendship
= 0x80,
172 k_EFriendFlagRequestingInfo
= 0x100,
173 k_EFriendFlagIgnored
= 0x200,
174 k_EFriendFlagIgnoredFriend
= 0x400,
175 // k_EFriendFlagSuggested = 0x800, // not used
176 k_EFriendFlagChatMember
= 0x1000,
177 k_EFriendFlagAll
= 0xFFFF,
181 // size limits on Rich Presence data
182 enum { k_cchMaxRichPresenceKeys
= 30 };
183 enum { k_cchMaxRichPresenceKeyLength
= 64 };
184 enum { k_cchMaxRichPresenceValueLength
= 256 };
186 /*______________________________________________________________________________________________________________________________
189 ______________________________________________________________________________________________________________________________*/
191 // Redefube class pointers to void
192 typedef void ISteamFriends
;
193 typedef void ISteamUserStats
;
194 typedef void ISteamUtils
;
195 typedef void ISteamUser
;
196 typedef void ISteamNetworking
;
198 typedef int32_t HSteamPipe
;
199 typedef int32_t HSteamUser
;
201 typedef int E_iCallBack_t
;
203 typedef uint32_t SNetSocket_t
; // CreateP2PConnectionSocket()
204 typedef uint32_t SNetListenSocket_t
; // CreateListenSocket()
206 typedef uint64_t uint64_steamid
;
207 typedef uint64_t SteamAPICall_t
;
209 /*______________________________________________________________________________________________________________________________
212 ______________________________________________________________________________________________________________________________*/
214 #pragma pack( push, 1 )
220 struct SteamIDComponent_t
222 #ifdef VALVE_BIG_ENDIAN
223 EUniverse_t m_EUniverse
: 8; // universe this account belongs to
224 unsigned int m_EAccountType
: 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
225 unsigned int m_unAccountInstance
: 20; // dynamic instance ID
226 uint32_t m_unAccountID
: 32; // unique account identifier
228 uint32_t m_unAccountID
: 32; // unique account identifier
229 unsigned int m_unAccountInstance
: 20; // dynamic instance ID
230 unsigned int m_EAccountType
: 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
231 EUniverse_t m_EUniverse
: 8; // universe this account belongs to
235 uint64_t m_unAll64Bits
;
242 uint32_t m_unIPv4
; // Host order
243 uint8_t m_rgubIPv6
[16]; // Network order! Same as inaddr_in6. (0011:2233:4455:6677:8899:aabb:ccdd:eeff)
246 uint64_t m_ipv6Qword
[2]; // big endian
250 ESteamIPType_t m_eType
;
256 /*______________________________________________________________________________________________________________________________
258 PACKING: Some kind of strange alignment thing
259 ______________________________________________________________________________________________________________________________*/
261 #if defined(__linux__) || defined(__APPLE__)
262 // The 32-bit version of gcc has the alignment requirement for uint64 and double set to
263 // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
264 // The 64-bit version of gcc has the alignment requirement for these types set to
265 // 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
266 // The 64-bit structure packing has to match the 32-bit structure packing for each platform.
267 #define VALVE_CALLBACK_PACK_SMALL
269 #define VALVE_CALLBACK_PACK_LARGE
272 #if defined( VALVE_CALLBACK_PACK_SMALL )
273 #pragma pack( push, 4 )
274 #elif defined( VALVE_CALLBACK_PACK_LARGE )
275 #pragma pack( push, 8 )
277 #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
282 uint8_t m_bConnectionActive
; // true if we've got an active open connection
283 uint8_t m_bConnecting
; // true if we're currently trying to establish a connection
284 uint8_t m_eP2PSessionError
; // last error recorded (see enum above)
285 uint8_t m_bUsingRelay
; // true if it's going through a relay server (TURN)
286 int32_t m_nBytesQueuedForSend
;
287 int32_t m_nPacketsQueuedForSend
;
288 uint32_t m_nRemoteIP
; // potential IP:Port of remote host. Could be TURN server.
289 uint16_t m_nRemotePort
; // Only exists for compatibility with older authentication api's
295 HSteamUser m_hSteamUser
; // Specific user to whom this callback applies.
296 int m_iCallback
; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
297 uint8_t *m_pubParam
; // Points to the callback structure
298 int m_cubParam
; // Size of the data pointed to by m_pubParam
304 SteamAPICall_t m_hAsyncCall
;
308 } SteamAPICallCompleted_t
;
309 #define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
312 // callback notification - a user wants to talk to us over the P2P channel via the SendP2PPacket() API
313 // in response, a call to AcceptP2PPacketsFromUser() needs to be made, if you want to talk with them
316 CSteamID m_steamIDRemote
; // user who wants to talk to us
318 } P2PSessionRequest_t
;
319 #define SW_CBID_P2PSessionRequest (k_iSteamNetworkingCallbacks + 2)
322 // callback notification - packets can't get through to the specified user via the SendP2PPacket() API
323 // all packets queued packets unsent at this point will be dropped
324 // further attempts to send will retry making the connection (but will be dropped if we fail again)
327 CSteamID m_steamIDRemote
; // user we were sending packets to
328 uint8_t m_eP2PSessionError
; // EP2PSessionError indicating why we're having trouble
330 } P2PSessionConnectFail_t
;
331 #define SW_CBID_P2PSessionConnectFail (k_iSteamNetworkingCallbacks + 3)
333 // callback notification - status of a socket has changed
334 // used as part of the CreateListenSocket() / CreateP2PConnectionSocket()
337 SNetSocket_t m_hSocket
; // the socket used to send/receive data to the remote host
338 SNetListenSocket_t m_hListenSocket
; // this is the server socket that we were listening on; NULL if this was an outgoing connection
339 CSteamID m_steamIDRemote
; // remote steamID we have connected to, if it has one
340 int m_eSNetSocketState
; // socket state, ESNetSocketState
342 } SocketStatusCallback_t
;
343 #define SW_CBID_SocketStatusCallback (k_iSteamNetworkingCallbacks + 1)
345 //-----------------------------------------------------------------------------
346 // Purpose: called when the user tries to join a game from their friends list
347 // rich presence will have been set with the "connect" key which is set here
348 //-----------------------------------------------------------------------------
350 CSteamID m_steamIDFriend
; // the friend they did the join via (will be invalid if not directly via a friend)
351 char m_rgchConnect
[k_cchMaxRichPresenceValueLength
];
352 } GameRichPresenceJoinRequested_t
;
353 #define SW_CBID_GameRichPresenceJoinRequested (k_iSteamFriendsCallbacks + 37)
355 // Making SURE we have alignment
356 #ifdef STRUCTURE_PACK_CHECK
362 } ValvePackingSentinel_t
;
369 /*______________________________________________________________________________________________________________________________
371 Forward linker declerations. Type: cdecl (obviously)
372 ______________________________________________________________________________________________________________________________*/
374 void SteamAPI_Shutdown();
376 int SteamAPI_RestartAppIfNecessary( uint32_t unOwnAppID
);
378 void SteamAPI_ManualDispatch_Init();
379 void SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe
);
380 int SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe
, CallbackMsg_t
*pCallbackMsg
);
381 void SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe
);
382 int SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe
, SteamAPICall_t hSteamAPICall
, void *pCallback
, int cubCallback
, int iCallbackExpected
, int *pbFailed
);
385 char *SteamAPI_ISteamFriends_GetPersonaName( ISteamFriends
*self
);
386 const char *SteamAPI_ISteamFriends_GetFriendPersonaName( ISteamFriends
*self
, uint64_steamid steamIDFriend
);
387 uint64_steamid
SteamAPI_ISteamUser_GetSteamID( ISteamUser
*self
);
388 int SteamAPI_ISteamFriends_SetRichPresence( ISteamFriends
* self
, const char * pchKey
, const char * pchValue
);
389 int SteamAPI_ISteamFriends_HasFriend( ISteamFriends
* self
, uint64_steamid steamIDFriend
, int iFriendFlags
);
390 int SteamAPI_ISteamFriends_GetSmallFriendAvatar ( ISteamFriends
*self
, uint64_steamid steamIDFriend
); // 32x32
391 int SteamAPI_ISteamFriends_GetMediumFriendAvatar ( ISteamFriends
*self
, uint64_steamid steamIDFriend
);
392 int SteamAPI_ISteamFriends_GetLargeFriendAvatar ( ISteamFriends
*self
, uint64_steamid steamIDFriend
);
393 int SteamAPI_ISteamUtils_GetImageSize( ISteamUtils
*self
, int iImage
, uint32_t *pnWidth
, uint32_t *pnHeight
);
394 int SteamAPI_ISteamUtils_GetImageRGBA( ISteamUtils
*self
, int iImage
, uint8_t *pubDest
, int nDestBufferSize
);
395 int SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats
*self
, const char *pchName
);
397 HSteamPipe
SteamAPI_GetHSteamPipe();
398 HSteamUser
SteamAPI_GetHSteamUser();
400 /* NETWORKING INTERFACES
401 -------------------------*/
403 int /* SendP2PPacket */ SteamAPI_ISteamNetworking_SendP2PPacket( ISteamNetworking
*self
,
404 uint64_steamid steamIDRemote
,
407 EP2PSend_t eP2PSendType
,
411 int /* IsP2PPacketAvailable */ SteamAPI_ISteamNetworking_IsP2PPacketAvailable( ISteamNetworking
*self
,
412 uint32_t *pcubMsgSize
,
416 int /* ReadP2PPacket */ SteamAPI_ISteamNetworking_ReadP2PPacket( ISteamNetworking
*self
,
419 uint32_t *pcubMsgSize
,
420 CSteamID
*psteamIDRemote
,
424 int /* AcceptP2PSessionWithUser */ SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser( ISteamNetworking
*self
,
425 uint64_steamid steamIDRemote
428 int /* CloseP2PSessionWithUser */ SteamAPI_ISteamNetworking_CloseP2PSessionWithUser( ISteamNetworking
*self
,
429 uint64_steamid steamIDRemote
432 int /* CloseP2PChannelWithUser */ SteamAPI_ISteamNetworking_CloseP2PChannelWithUser( ISteamNetworking
*self
,
433 uint64_steamid steamIDRemote
,
437 int /* GetP2PSessionState */ SteamAPI_ISteamNetworking_GetP2PSessionState( ISteamNetworking
*self
,
438 uint64_steamid steamIDRemote
,
439 P2PSessionState_t
*pConnectionState
442 int /* AllowP2PPacketRelay */ SteamAPI_ISteamNetworking_AllowP2PPacketRelay( ISteamNetworking
*self
,
446 SNetListenSocket_t
/* CreateListenSocket */ SteamAPI_ISteamNetworking_CreateListenSocket( ISteamNetworking
*self
,
448 SteamIPAddress_t nIP
,
450 int bAllowUseOfPacketRelay
453 SNetSocket_t
/* CreateP2PConnectionSocket */ SteamAPI_ISteamNetworking_CreateP2PConnectionSocket( ISteamNetworking
*self
,
454 uint64_steamid steamIDTarget
,
457 int bAllowUseOfPacketRelay
460 SNetSocket_t
/* CreateConnectionSocket */ SteamAPI_ISteamNetworking_CreateConnectionSocket( ISteamNetworking
*self
,
461 SteamIPAddress_t nIP
,
466 int /* DestroySocket */ SteamAPI_ISteamNetworking_DestroySocket( ISteamNetworking
*self
,
467 SNetSocket_t hSocket
,
471 int /* DestroyListenSocket */ SteamAPI_ISteamNetworking_DestroyListenSocket( ISteamNetworking
*self
,
472 SNetListenSocket_t hSocket
,
476 int /* SendDataOnSocket */ SteamAPI_ISteamNetworking_SendDataOnSocket( ISteamNetworking
*self
,
477 SNetSocket_t hSocket
,
483 int /* IsDataAvailableOnSocket */ SteamAPI_ISteamNetworking_IsDataAvailableOnSocket( ISteamNetworking
*self
,
484 SNetSocket_t hSocket
,
485 uint32_t *pcubMsgSize
488 int /* RetrieveDataFromSocket */ SteamAPI_ISteamNetworking_RetrieveDataFromSocket( ISteamNetworking
*self
,
489 SNetSocket_t hSocket
,
492 uint32_t *pcubMsgSize
495 int /* IsDataAvailable */ SteamAPI_ISteamNetworking_IsDataAvailable( ISteamNetworking
*self
,
496 SNetListenSocket_t hListenSocket
,
497 uint32_t *pcubMsgSize
,
498 SNetSocket_t
*phSocket
501 int /* RetrieveData */ SteamAPI_ISteamNetworking_RetrieveData( ISteamNetworking
*self
,
502 SNetListenSocket_t hListenSocket
,
505 uint32_t *pcubMsgSize
,
506 SNetSocket_t
*phSocket
509 int /* GetSocketInfo */ SteamAPI_ISteamNetworking_GetSocketInfo( ISteamNetworking
*self
,
510 SNetSocket_t hSocket
,
511 CSteamID
*pSteamIDRemote
,
513 SteamIPAddress_t
*punIPRemote
,
514 uint16_t *punPortRemote
517 int /* GetListenSocketInfo */ SteamAPI_ISteamNetworking_GetListenSocketInfo( ISteamNetworking
*self
,
518 SNetListenSocket_t hListenSocket
,
519 SteamIPAddress_t
*pnIP
,
523 ESNetSocketConnectionType_t
/* GetSocketConnectionType */ SteamAPI_ISteamNetworking_GetSocketConnectionType( ISteamNetworking
*self
,
527 int /* GetMaxPacketSize */ SteamAPI_ISteamNetworking_GetMaxPacketSize( ISteamNetworking
*self
,
531 #define sw_SteamAPI_Shutdown SteamAPI_Shutdown
532 #define sw_SteamAPI_Init() SteamAPI_Init()
533 #define sw_SteamAPI_RestartAppIfNecessary(...) SteamAPI_RestartAppIfNecessary( __VA_ARGS__ )
535 // This method can only be cleared correctly in first party c++ mode
536 // See: sw_SteamAPI_ManualDispatch_Init
537 // #define sw_SteamAPI_RunCallbacks()
540 #define sw_SteamAPI_GetHSteamPipe() SteamAPI_GetHSteamPipe()
541 #define sw_SteamAPI_GetHSteamUser() SteamAPI_GetHSteamUser()
543 #define sw_SteamAPI_ManualDispatch_Init() SteamAPI_ManualDispatch_Init()
544 #define sw_SteamAPI_ManualDispatch_GetNextCallback(...) SteamAPI_ManualDispatch_GetNextCallback( __VA_ARGS__ )
545 #define sw_SteamAPI_ManualDispatch_FreeLastCallback(...) SteamAPI_ManualDispatch_FreeLastCallback( __VA_ARGS__ )
546 #define sw_SteamAPI_ManualDispatch_GetAPICallResult(...) SteamAPI_ManualDispatch_GetAPICallResult( __VA_ARGS__ )
547 #define sw_SteamAPI_ManualDispatch_RunFrame(...) SteamAPI_ManualDispatch_RunFrame( __VA_ARGS__ )
549 #define sw_GetPersonaName(...) SteamAPI_ISteamFriends_GetPersonaName( __thinsteam_friends, ##__VA_ARGS__ )
550 #define sw_GetFriendPersonaName(...) SteamAPI_ISteamFriends_GetFriendPersonaName( __thinsteam_friends, __VA_ARGS__ )
551 #define sw_GetSteamID(...) SteamAPI_ISteamUser_GetSteamID( __thinsteam_user, ##__VA_ARGS__ )
552 #define sw_HasFriend(...) SteamAPI_ISteamFriends_HasFriend( __thinsteam_friends, __VA_ARGS__ )
553 #define sw_SetRichPresence(...) SteamAPI_ISteamFriends_SetRichPresence( __thinsteam_friends, __VA_ARGS__ )
555 #define sw_GetSmallFriendAvatar(...) SteamAPI_ISteamFriends_GetSmallFriendAvatar( __thinsteam_friends, ##__VA_ARGS__ )
556 #define sw_GetMediumFriendAvatar(...) SteamAPI_ISteamFriends_GetMediumFriendAvatar( __thinsteam_friends, ##__VA_ARGS__ )
557 #define sw_GetLargeFriendAvatar(...) SteamAPI_ISteamFriends_GetLargeFriendAvatar( __thinsteam_friends, ##__VA_ARGS__ )
558 #define sw_GetImageSize(...) SteamAPI_ISteamUtils_GetImageSize( __thinsteam_utils, ##__VA_ARGS__ )
559 #define sw_GetImageRGBA(...) SteamAPI_ISteamUtils_GetImageRGBA( __thinsteam_utils, ##__VA_ARGS__ )
561 #define sw_SetAchievement(...) SteamAPI_ISteamUserStats_SetAchievement( __thinsteam_stats, ##__VA_ARGS__ )
563 // https://partner.steamgames.com/doc/api/ISteamNetworkingUtils
564 #define sw_SendP2PPacket(...) SteamAPI_ISteamNetworking_SendP2PPacket( __thinsteam_net, ##__VA_ARGS__ )
565 #define sw_IsP2PPacketAvailable(...) SteamAPI_ISteamNetworking_IsP2PPacketAvailable( __thinsteam_net, ##__VA_ARGS__ )
566 #define sw_ReadP2PPacket(...) SteamAPI_ISteamNetworking_ReadP2PPacket( __thinsteam_net, ##__VA_ARGS__ )
567 #define sw_AcceptP2PSessionWithUser(...) SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser( __thinsteam_net, ##__VA_ARGS__ )
568 #define sw_CloseP2PSessionWithUser(...) SteamAPI_ISteamNetworking_CloseP2PSessionWithUser( __thinsteam_net, ##__VA_ARGS__ )
569 #define sw_CloseP2PChannelWithUser(...) SteamAPI_ISteamNetworking_CloseP2PChannelWithUser( __thinsteam_net, ##__VA_ARGS__ )
570 #define sw_GetP2PSessionState(...) SteamAPI_ISteamNetworking_GetP2PSessionState( __thinsteam_net, ##__VA_ARGS__ )
571 #define sw_AllowP2PPacketRelay(...) SteamAPI_ISteamNetworking_AllowP2PPacketRelay( __thinsteam_net, ##__VA_ARGS__ )
572 #define sw_CreateListenSocket(...) SteamAPI_ISteamNetworking_CreateListenSocket( __thinsteam_net, ##__VA_ARGS__ )
573 #define sw_CreateP2PConnectionSocket(...) SteamAPI_ISteamNetworking_CreateP2PConnectionSocket( __thinsteam_net, ##__VA_ARGS__ )
574 #define sw_CreateConnectionSocket(...) SteamAPI_ISteamNetworking_CreateConnectionSocket( __thinsteam_net, ##__VA_ARGS__ )
575 #define sw_DestroySocket(...) SteamAPI_ISteamNetworking_DestroySocket( __thinsteam_net, ##__VA_ARGS__ )
576 #define sw_DestroyListenSocket(...) SteamAPI_ISteamNetworking_DestroyListenSocket( __thinsteam_net, ##__VA_ARGS__ )
577 #define sw_SendDataOnSocket(...) SteamAPI_ISteamNetworking_SendDataOnSocket( __thinsteam_net, ##__VA_ARGS__ )
578 #define sw_IsDataAvailableOnSocket(...) SteamAPI_ISteamNetworking_IsDataAvailableOnSocket( __thinsteam_net, ##__VA_ARGS__ )
579 #define sw_RetrieveDataFromSocket(...) SteamAPI_ISteamNetworking_RetrieveDataFromSocket( __thinsteam_net, ##__VA_ARGS__ )
580 #define sw_IsDataAvailable(...) SteamAPI_ISteamNetworking_IsDataAvailable( __thinsteam_net, ##__VA_ARGS__ )
581 #define sw_RetrieveData(...) SteamAPI_ISteamNetworking_RetrieveData( __thinsteam_net, ##__VA_ARGS__ )
582 #define sw_GetSocketInfo(...) SteamAPI_ISteamNetworking_GetSocketInfo( __thinsteam_net, ##__VA_ARGS__ )
583 #define sw_GetListenSocketInfo(...) SteamAPI_ISteamNetworking_GetListenSocketInfo( __thinsteam_net, ##__VA_ARGS__ )
584 #define sw_GetSocketConnectionType(...) SteamAPI_ISteamNetworking_GetSocketConnectionType( __thinsteam_net,##__VA_ARGS__ )
585 #define sw_GetMaxPacketSize(...) SteamAPI_ISteamNetworking_GetMaxPacketSize( __thinsteam_net, ##__VA_ARGS__ )
587 #define _sw__fill( self, func, ... ) func( self, ##__VA_ARGS__ )
590 /*______________________________________________________________________________________________________________________________
593 ______________________________________________________________________________________________________________________________*/
595 ISteamFriends
*__thinsteam_friends
= NULL
;
596 ISteamUser
*__thinsteam_user
= NULL
;
597 ISteamUtils
*__thinsteam_utils
= NULL
;
598 ISteamUserStats
*__thinsteam_stats
= NULL
;
599 ISteamNetworking
*__thinsteam_net
= NULL
;
601 ISteamFriends
*SteamAPI_SteamFriends_v017();
602 ISteamUser
*SteamAPI_SteamUser_v021();
603 ISteamUtils
*SteamAPI_SteamUtils_v009();
604 ISteamUserStats
*SteamAPI_SteamUserStats_v012();
605 ISteamNetworking
*SteamAPI_SteamNetworking_v006();
607 HSteamPipe g_hSteamPipe
;
609 GLuint
get_player_image( uint64_steamid usr
)
613 uint32_t x
= 64, y
= 64;
616 steam_image
= sw_GetMediumFriendAvatar( usr
);
617 sw_GetImageSize( steam_image
, &x
, &y
);
619 unsigned char * img_buf
= (unsigned char *)calloc( x
* y
* 4, 1 );
621 sw_GetImageRGBA( steam_image
, img_buf
, x
* y
* 4 );
623 glGenTextures( 1, &gl_img
);
624 glBindTexture( GL_TEXTURE_2D
, gl_img
);
626 glTexImage2D( GL_TEXTURE_2D
, 0, GL_RGBA
, x
, y
, 0, GL_RGBA
, GL_UNSIGNED_BYTE
, img_buf
);
627 glGenerateMipmap( GL_TEXTURE_2D
);
629 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
630 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
632 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
633 glTexParameteri( GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
640 int sw_vipid( uint64_steamid usr
)
642 static uint64_steamid massiveLEGENDS
[] =
644 76561198134179460, // Spud
645 76561198020563704, // Assasssin
646 76561198062961277, // lopen
647 76561198084693332 // ernie
650 for( int i
= 0; i
< sizeof(massiveLEGENDS
)/sizeof(massiveLEGENDS
[0]); i
++ )
652 if( massiveLEGENDS
[i
] == usr
)
659 // Initialize steamworks through this function and your appid
660 int sw_init( uint32_t appid
) {
662 #ifdef STRUCTURE_PACK_CHECK
664 // This code should never fail and if it does something went wrong with the build
665 // Remember to undefine STRUCTURE_PACK_CHECK for publishing!!!
667 #if defined(VALVE_CALLBACK_PACK_SMALL)
668 if( sizeof(ValvePackingSentinel_t
) != 24 ){
669 printf( "Struct packing error: ValvePackingSentinel_t expected 24 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t
));
672 #elif defined(VALVE_CALLBACK_PACK_LARGE)
673 if( sizeof(ValvePackingSentinel_t
) != 32 ){
674 printf( "Struct packing error: ValvePackingSentinel_t expected 32 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t
));
683 #ifdef STEAMWORKS_VERBOSE
684 printf( "Initializing steamworks..\n" );
687 if( sw_SteamAPI_RestartAppIfNecessary( appid
) == 1 ){
688 #ifdef STEAMWORKS_VERBOSE
689 printf( "Restarting via steam\n" );
694 if( !sw_SteamAPI_Init() ){
695 #ifdef STEAMWORKS_VERBOSE
696 printf( "Steamworks connection failed\n" );
701 // We are using C so we have to deal with callbacks microsoft event loop style
702 sw_SteamAPI_ManualDispatch_Init();
704 __thinsteam_friends
= SteamAPI_SteamFriends_v017();
705 __thinsteam_user
= SteamAPI_SteamUser_v021();
706 __thinsteam_utils
= SteamAPI_SteamUtils_v009();
707 __thinsteam_stats
= SteamAPI_SteamUserStats_v012();
708 __thinsteam_net
= SteamAPI_SteamNetworking_v006();
710 // This might happen if the DLL is too old
711 if( !__thinsteam_friends
| !__thinsteam_user
| !__thinsteam_utils
| !__thinsteam_stats
| !__thinsteam_net
){
712 #ifdef STEAMWORKS_VERBOSE
713 printf( "Interface hooks failed\n" );
718 g_hSteamPipe
= sw_SteamAPI_GetHSteamPipe();
720 #ifdef STEAMWORKS_VERBOSE
721 printf( "Steamworks ready\n" );
727 void sw_init_postgl()
729 _localplayer_image
= get_player_image( sw_GetSteamID() );
730 strcpy( _localplayer_name
, sw_GetPersonaName() );
733 /*______________________________________________________________________________________________________________________________
736 ______________________________________________________________________________________________________________________________*/
738 // Macro Creates <name>(args):
739 // Function(args) pointer definition
740 // <name> Callback global pointer
741 // sw_Set<name>Callback (*ptr) function
743 #define _swCallbackPair( CNAME, ... ) \
744 typedef void(*sw_##CNAME##Fun)( __VA_ARGS__ ); \
745 sw_##CNAME##Fun CNAME = NULL; \
746 void sw_Set##CNAME##Callback(sw_##CNAME##Fun d) { CNAME = d; }
748 _swCallbackPair( OnSocketStatus
, SNetSocket_t
, SNetListenSocket_t
, CSteamID
, int )
749 _swCallbackPair( OnP2PSessionConnectFail
, CSteamID
, EP2PSessionError_t
)
750 _swCallbackPair( OnP2PSessionRequest
, CSteamID
)
751 _swCallbackPair( OnSteamJoinRequest
, CSteamID
, char * )
753 void sw_RunSteamEventLoop(void)
755 sw_SteamAPI_ManualDispatch_RunFrame( g_hSteamPipe
);
756 CallbackMsg_t callback
;
757 while( sw_SteamAPI_ManualDispatch_GetNextCallback( g_hSteamPipe
, &callback
) ){
759 // Check for dispatching API call results
760 if( callback
.m_iCallback
== SW_CBID_SteamAPICallCompleted
){
762 SteamAPICallCompleted_t
*pCallCompleted
= (SteamAPICallCompleted_t
*)&callback
;
763 void *pTmpCallResult
= malloc( pCallCompleted
->m_cubParam
);
766 if( sw_SteamAPI_ManualDispatch_GetAPICallResult( g_hSteamPipe
, pCallCompleted
->m_hAsyncCall
, pTmpCallResult
, \
767 pCallCompleted
->m_cubParam
, pCallCompleted
->m_iCallback
, &bFailed
) ){
769 // Dispatch the call result to the registered handler(s) for the
770 // call identified by pCallCompleted->m_hAsyncCall
774 free( pTmpCallResult
);
778 // Look at callback.m_iCallback to see what kind of callback it is,
779 // and dispatch to appropriate handler(s)
781 vg_info( "steamworks_event::callback( %i )\n", callback
.m_iCallback
);
783 void *data
= callback
.m_pubParam
;
785 switch( callback
.m_iCallback
){
787 case SW_CBID_P2PSessionRequest
: if( OnP2PSessionRequest
) OnP2PSessionRequest(
788 ((P2PSessionRequest_t
*)data
)->m_steamIDRemote
791 case SW_CBID_SocketStatusCallback
: if( OnSocketStatus
) OnSocketStatus(
792 ((SocketStatusCallback_t
*)data
)->m_hSocket
,
793 ((SocketStatusCallback_t
*)data
)->m_hListenSocket
,
794 ((SocketStatusCallback_t
*)data
)->m_steamIDRemote
,
795 ((SocketStatusCallback_t
*)data
)->m_eSNetSocketState
798 case SW_CBID_P2PSessionConnectFail
: if( OnP2PSessionConnectFail
) OnP2PSessionConnectFail(
799 ((P2PSessionConnectFail_t
*)data
)->m_steamIDRemote
,
800 ((P2PSessionConnectFail_t
*)data
)->m_eP2PSessionError
803 case SW_CBID_GameRichPresenceJoinRequested
: if( OnSteamJoinRequest
) OnSteamJoinRequest(
804 ((GameRichPresenceJoinRequested_t
*)data
)->m_steamIDFriend
,
805 ((GameRichPresenceJoinRequested_t
*)data
)->m_rgchConnect
814 SteamAPI_ManualDispatch_FreeLastCallback( g_hSteamPipe
);
820 /*______________________________________________________________________________________________________________________________
823 ______________________________________________________________________________________________________________________________*/
825 #else // #define NO_STEAM
826 // In case we dont want to spam the steam servers
828 char *__str_sw_unlinked
= "__NO_STEAMWORKS__";
830 #define SW_BLANK_RETURN 0
832 #define sw_init( x ) 1
834 #define sw_runcallbacks()
835 #define sw_get_persona_name() __str_sw_unlinked
836 #define sw_get_steamid() SW_BLANK_RETURN
837 #define sw_get_friend_smallavatar( x ) SW_BLANK_RETURN
838 #define sw_get_friend_mediumavatar( x ) SW_BLANK_RETURN
839 #define sw_get_friend_largeavatar( x ) SW_BLANK_RETURN
841 #define sw_get_image_size( x, y, z )
842 #define sw_get_image_rgba( x, y, z )
843 #define sw_set_achievement( x )