5c6397bb667707abf805d01af9ce6cf0dadb1c4f
[fishladder.git] / steam / steamworks_thin.h
1 /*
2 steamworks_thin.h - simple wrapper / macro set for building steamworks apps in pure C
3 Usage:
4 Put the latest steam_api.dll in your build folder
5 link against -lsteam_api
6
7 all functions are prefixed with sw_
8 */
9
10 #ifndef STEAMWORKS_H
11 #define STEAMWORKS_H
12
13 #include <stdint.h>
14 #include <stdio.h>
15
16 GLuint _localplayer_image;
17 char _localplayer_name[128];
18
19 #ifndef NO_STEAM
20
21 #ifndef VOYAGER_RELEASE_MODE
22 #define STRUCTURE_PACK_CHECK
23 #endif
24
25 /*______________________________________________________________________________________________________________________________
26
27 ENUMS
28 ______________________________________________________________________________________________________________________________*/
29
30 typedef enum{
31
32 k_ESteamIPTypeIPv4 = 0,
33 k_ESteamIPTypeIPv6 = 1,
34
35 } ESteamIPType_t;
36
37 typedef enum{
38
39 k_ESNetSocketConnectionTypeNotConnected = 0,
40 k_ESNetSocketConnectionTypeUDP = 1,
41 k_ESNetSocketConnectionTypeUDPRelay = 2,
42
43 } ESNetSocketConnectionType_t;
44
45 //-----------------------------------------------------------------------------
46 // Purpose: Base values for callback identifiers, each callback must
47 // have a unique ID.
48 //-----------------------------------------------------------------------------
49
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 };
112
113 // Steam universes. Each universe is a self-contained Steam instance.
114 typedef enum {
115 k_EUniverseInvalid = 0,
116 k_EUniversePublic = 1,
117 k_EUniverseBeta = 2,
118 k_EUniverseInternal = 3,
119 k_EUniverseDev = 4,
120 // k_EUniverseRC = 5, // no such universe anymore
121 k_EUniverseMax
122 } EUniverse_t;
123
124 typedef enum{
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,
129
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,
134
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,
138
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,
145
146 } EP2PSend_t;
147
148 // list of possible errors returned by SendP2PPacket() API
149 // these will be posted in the P2PSessionConnectFail_t callback
150 typedef enum {
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;
160
161 typedef enum {
162
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,
178
179 } EFriendFlags_t;
180
181 // size limits on Rich Presence data
182 enum { k_cchMaxRichPresenceKeys = 30 };
183 enum { k_cchMaxRichPresenceKeyLength = 64 };
184 enum { k_cchMaxRichPresenceValueLength = 256 };
185
186 /*______________________________________________________________________________________________________________________________
187
188 STEAM TYPES
189 ______________________________________________________________________________________________________________________________*/
190
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;
197
198 typedef int32_t HSteamPipe;
199 typedef int32_t HSteamUser;
200
201 typedef int E_iCallBack_t;
202
203 typedef uint32_t SNetSocket_t; // CreateP2PConnectionSocket()
204 typedef uint32_t SNetListenSocket_t; // CreateListenSocket()
205
206 typedef uint64_t uint64_steamid;
207 typedef uint64_t SteamAPICall_t;
208
209 /*______________________________________________________________________________________________________________________________
210
211 PACKING: 1 Byte
212 ______________________________________________________________________________________________________________________________*/
213
214 #pragma pack( push, 1 )
215
216 typedef struct
217 {
218 // 64 bits total
219 union {
220 struct SteamIDComponent_t
221 {
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
227 #else
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
232 #endif
233 } m_comp;
234
235 uint64_t m_unAll64Bits;
236 };
237 } CSteamID;
238
239 typedef struct{
240 union {
241
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)
244
245 // Internal use only
246 uint64_t m_ipv6Qword[2]; // big endian
247
248 };
249
250 ESteamIPType_t m_eType;
251
252 } SteamIPAddress_t;
253
254 #pragma pack(pop)
255
256 /*______________________________________________________________________________________________________________________________
257
258 PACKING: Some kind of strange alignment thing
259 ______________________________________________________________________________________________________________________________*/
260
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
268 #else
269 #define VALVE_CALLBACK_PACK_LARGE
270 #endif
271
272 #if defined( VALVE_CALLBACK_PACK_SMALL )
273 #pragma pack( push, 4 )
274 #elif defined( VALVE_CALLBACK_PACK_LARGE )
275 #pragma pack( push, 8 )
276 #else
277 #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
278 #endif
279
280 typedef struct{
281
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
290
291 } P2PSessionState_t;
292
293 typedef struct {
294
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
299
300 } CallbackMsg_t;
301
302 typedef struct {
303
304 SteamAPICall_t m_hAsyncCall;
305 int m_iCallback;
306 uint32_t m_cubParam;
307
308 } SteamAPICallCompleted_t;
309 #define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
310
311
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
314 typedef struct {
315
316 CSteamID m_steamIDRemote; // user who wants to talk to us
317
318 } P2PSessionRequest_t;
319 #define SW_CBID_P2PSessionRequest (k_iSteamNetworkingCallbacks + 2)
320
321
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)
325 typedef struct {
326
327 CSteamID m_steamIDRemote; // user we were sending packets to
328 uint8_t m_eP2PSessionError; // EP2PSessionError indicating why we're having trouble
329
330 } P2PSessionConnectFail_t;
331 #define SW_CBID_P2PSessionConnectFail (k_iSteamNetworkingCallbacks + 3)
332
333 // callback notification - status of a socket has changed
334 // used as part of the CreateListenSocket() / CreateP2PConnectionSocket()
335 typedef struct {
336
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
341
342 } SocketStatusCallback_t;
343 #define SW_CBID_SocketStatusCallback (k_iSteamNetworkingCallbacks + 1)
344
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 //-----------------------------------------------------------------------------
349 typedef struct {
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)
354
355 // Making SURE we have alignment
356 #ifdef STRUCTURE_PACK_CHECK
357 typedef struct {
358 uint32_t m_u32;
359 uint64_t m_u64;
360 uint16_t m_u16;
361 double m_d;
362 } ValvePackingSentinel_t;
363 #endif
364
365 #pragma pack( pop )
366
367 #ifndef NO_STEAM
368
369 /*______________________________________________________________________________________________________________________________
370
371 Forward linker declerations. Type: cdecl (obviously)
372 ______________________________________________________________________________________________________________________________*/
373
374 void SteamAPI_Shutdown();
375 int SteamAPI_Init();
376 int SteamAPI_RestartAppIfNecessary( uint32_t unOwnAppID );
377
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 );
383
384
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 );
396
397 HSteamPipe SteamAPI_GetHSteamPipe();
398 HSteamUser SteamAPI_GetHSteamUser();
399
400 /* NETWORKING INTERFACES
401 -------------------------*/
402
403 int /* SendP2PPacket */ SteamAPI_ISteamNetworking_SendP2PPacket( ISteamNetworking *self,
404 uint64_steamid steamIDRemote,
405 const void *pubData,
406 uint32_t cubData,
407 EP2PSend_t eP2PSendType,
408 int nChannel
409 );
410
411 int /* IsP2PPacketAvailable */ SteamAPI_ISteamNetworking_IsP2PPacketAvailable( ISteamNetworking *self,
412 uint32_t *pcubMsgSize,
413 int nChannel
414 );
415
416 int /* ReadP2PPacket */ SteamAPI_ISteamNetworking_ReadP2PPacket( ISteamNetworking *self,
417 void *pubDest,
418 uint32_t cubDest,
419 uint32_t *pcubMsgSize,
420 CSteamID *psteamIDRemote,
421 int nChannel
422 );
423
424 int /* AcceptP2PSessionWithUser */ SteamAPI_ISteamNetworking_AcceptP2PSessionWithUser( ISteamNetworking *self,
425 uint64_steamid steamIDRemote
426 );
427
428 int /* CloseP2PSessionWithUser */ SteamAPI_ISteamNetworking_CloseP2PSessionWithUser( ISteamNetworking *self,
429 uint64_steamid steamIDRemote
430 );
431
432 int /* CloseP2PChannelWithUser */ SteamAPI_ISteamNetworking_CloseP2PChannelWithUser( ISteamNetworking *self,
433 uint64_steamid steamIDRemote,
434 int nChannel
435 );
436
437 int /* GetP2PSessionState */ SteamAPI_ISteamNetworking_GetP2PSessionState( ISteamNetworking *self,
438 uint64_steamid steamIDRemote,
439 P2PSessionState_t *pConnectionState
440 );
441
442 int /* AllowP2PPacketRelay */ SteamAPI_ISteamNetworking_AllowP2PPacketRelay( ISteamNetworking *self,
443 int bAllow
444 );
445
446 SNetListenSocket_t /* CreateListenSocket */ SteamAPI_ISteamNetworking_CreateListenSocket( ISteamNetworking *self,
447 int nVirtualP2PPort,
448 SteamIPAddress_t nIP,
449 uint16_t nPort,
450 int bAllowUseOfPacketRelay
451 );
452
453 SNetSocket_t /* CreateP2PConnectionSocket */ SteamAPI_ISteamNetworking_CreateP2PConnectionSocket( ISteamNetworking *self,
454 uint64_steamid steamIDTarget,
455 int nVirtualPort,
456 int nTimeoutSec,
457 int bAllowUseOfPacketRelay
458 );
459
460 SNetSocket_t /* CreateConnectionSocket */ SteamAPI_ISteamNetworking_CreateConnectionSocket( ISteamNetworking *self,
461 SteamIPAddress_t nIP,
462 uint16_t nPort,
463 int nTimeoutSec
464 );
465
466 int /* DestroySocket */ SteamAPI_ISteamNetworking_DestroySocket( ISteamNetworking *self,
467 SNetSocket_t hSocket,
468 int bNotifyRemoteEnd
469 );
470
471 int /* DestroyListenSocket */ SteamAPI_ISteamNetworking_DestroyListenSocket( ISteamNetworking *self,
472 SNetListenSocket_t hSocket,
473 int bNotifyRemoteEnd
474 );
475
476 int /* SendDataOnSocket */ SteamAPI_ISteamNetworking_SendDataOnSocket( ISteamNetworking *self,
477 SNetSocket_t hSocket,
478 void *pubData,
479 uint32_t cubData,
480 int bReliable
481 );
482
483 int /* IsDataAvailableOnSocket */ SteamAPI_ISteamNetworking_IsDataAvailableOnSocket( ISteamNetworking *self,
484 SNetSocket_t hSocket,
485 uint32_t *pcubMsgSize
486 );
487
488 int /* RetrieveDataFromSocket */ SteamAPI_ISteamNetworking_RetrieveDataFromSocket( ISteamNetworking *self,
489 SNetSocket_t hSocket,
490 void *pubDest,
491 uint32_t cubDest,
492 uint32_t *pcubMsgSize
493 );
494
495 int /* IsDataAvailable */ SteamAPI_ISteamNetworking_IsDataAvailable( ISteamNetworking *self,
496 SNetListenSocket_t hListenSocket,
497 uint32_t *pcubMsgSize,
498 SNetSocket_t *phSocket
499 );
500
501 int /* RetrieveData */ SteamAPI_ISteamNetworking_RetrieveData( ISteamNetworking *self,
502 SNetListenSocket_t hListenSocket,
503 void *pubDest,
504 uint32_t cubDest,
505 uint32_t *pcubMsgSize,
506 SNetSocket_t *phSocket
507 );
508
509 int /* GetSocketInfo */ SteamAPI_ISteamNetworking_GetSocketInfo( ISteamNetworking *self,
510 SNetSocket_t hSocket,
511 CSteamID *pSteamIDRemote,
512 int *peSocketStatus,
513 SteamIPAddress_t *punIPRemote,
514 uint16_t *punPortRemote
515 );
516
517 int /* GetListenSocketInfo */ SteamAPI_ISteamNetworking_GetListenSocketInfo( ISteamNetworking *self,
518 SNetListenSocket_t hListenSocket,
519 SteamIPAddress_t *pnIP,
520 uint16_t *pnPort
521 );
522
523 ESNetSocketConnectionType_t /* GetSocketConnectionType */ SteamAPI_ISteamNetworking_GetSocketConnectionType( ISteamNetworking *self,
524 SNetSocket_t hSocket
525 );
526
527 int /* GetMaxPacketSize */ SteamAPI_ISteamNetworking_GetMaxPacketSize( ISteamNetworking *self,
528 SNetSocket_t hSocket
529 );
530
531 #define sw_SteamAPI_Shutdown SteamAPI_Shutdown
532 #define sw_SteamAPI_Init() SteamAPI_Init()
533 #define sw_SteamAPI_RestartAppIfNecessary(...) SteamAPI_RestartAppIfNecessary( __VA_ARGS__ )
534
535 // This method can only be cleared correctly in first party c++ mode
536 // See: sw_SteamAPI_ManualDispatch_Init
537 // #define sw_SteamAPI_RunCallbacks()
538
539 // Steam pipe stuff
540 #define sw_SteamAPI_GetHSteamPipe() SteamAPI_GetHSteamPipe()
541 #define sw_SteamAPI_GetHSteamUser() SteamAPI_GetHSteamUser()
542
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__ )
548
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__ )
554
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__ )
560
561 #define sw_SetAchievement(...) SteamAPI_ISteamUserStats_SetAchievement( __thinsteam_stats, ##__VA_ARGS__ )
562
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__ )
586
587 #define _sw__fill( self, func, ... ) func( self, ##__VA_ARGS__ )
588 #endif
589
590 /*______________________________________________________________________________________________________________________________
591
592 WRAPPER LAYER
593 ______________________________________________________________________________________________________________________________*/
594
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;
600
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();
606
607 HSteamPipe g_hSteamPipe;
608
609 GLuint get_player_image( uint64_steamid usr )
610 {
611 GLuint gl_img;
612
613 uint32_t x = 64, y = 64;
614 int steam_image;
615
616 steam_image = sw_GetMediumFriendAvatar( usr );
617 sw_GetImageSize( steam_image, &x, &y );
618
619 unsigned char * img_buf = (unsigned char *)calloc( x * y * 4, 1 );
620
621 sw_GetImageRGBA( steam_image, img_buf, x * y * 4 );
622
623 glGenTextures( 1, &gl_img );
624 glBindTexture( GL_TEXTURE_2D, gl_img );
625
626 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_buf );
627 glGenerateMipmap( GL_TEXTURE_2D );
628
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 );
631
632 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
633 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
634
635 free( img_buf );
636
637 return gl_img;
638 }
639
640 int sw_vipid( uint64_steamid usr )
641 {
642 static uint64_steamid massiveLEGENDS[] =
643 {
644 76561198134179460, // Spud
645 76561198020563704, // Assasssin
646 76561198062961277, // lopen
647 76561198084693332 // ernie
648 };
649
650 for( int i = 0; i < sizeof(massiveLEGENDS)/sizeof(massiveLEGENDS[0]); i ++ )
651 {
652 if( massiveLEGENDS[i] == usr )
653 return 1;
654 }
655
656 return 0;
657 }
658
659 // Initialize steamworks through this function and your appid
660 int sw_init( uint32_t appid ) {
661
662 #ifdef STRUCTURE_PACK_CHECK
663
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!!!
666
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));
670 return 0;
671 }
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));
675 return 0;
676 }
677 #else
678 #error ???
679 #endif
680
681 #endif
682
683 #ifdef STEAMWORKS_VERBOSE
684 printf( "Initializing steamworks..\n" );
685 #endif
686
687 if( sw_SteamAPI_RestartAppIfNecessary( appid ) == 1 ){
688 #ifdef STEAMWORKS_VERBOSE
689 printf( "Restarting via steam\n" );
690 #endif
691 return 0;
692 }
693
694 if( !sw_SteamAPI_Init() ){
695 #ifdef STEAMWORKS_VERBOSE
696 printf( "Steamworks connection failed\n" );
697 #endif
698 return 0;
699 }
700
701 // We are using C so we have to deal with callbacks microsoft event loop style
702 sw_SteamAPI_ManualDispatch_Init();
703
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();
709
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" );
714 #endif
715 return 0;
716 }
717
718 g_hSteamPipe = sw_SteamAPI_GetHSteamPipe();
719
720 #ifdef STEAMWORKS_VERBOSE
721 printf( "Steamworks ready\n" );
722 #endif
723
724 return 1;
725 }
726
727 void sw_init_postgl()
728 {
729 _localplayer_image = get_player_image( sw_GetSteamID() );
730 strcpy( _localplayer_name, sw_GetPersonaName() );
731 }
732
733 /*______________________________________________________________________________________________________________________________
734
735 USER CODE
736 ______________________________________________________________________________________________________________________________*/
737
738 // Macro Creates <name>(args):
739 // Function(args) pointer definition
740 // <name> Callback global pointer
741 // sw_Set<name>Callback (*ptr) function
742
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; }
747
748 _swCallbackPair( OnSocketStatus, SNetSocket_t, SNetListenSocket_t, CSteamID, int )
749 _swCallbackPair( OnP2PSessionConnectFail, CSteamID, EP2PSessionError_t )
750 _swCallbackPair( OnP2PSessionRequest, CSteamID )
751 _swCallbackPair( OnSteamJoinRequest, CSteamID, char * )
752
753 void sw_RunSteamEventLoop(void)
754 {
755 sw_SteamAPI_ManualDispatch_RunFrame( g_hSteamPipe );
756 CallbackMsg_t callback;
757 while( sw_SteamAPI_ManualDispatch_GetNextCallback( g_hSteamPipe, &callback ) ){
758
759 // Check for dispatching API call results
760 if( callback.m_iCallback == SW_CBID_SteamAPICallCompleted ){
761
762 SteamAPICallCompleted_t *pCallCompleted = (SteamAPICallCompleted_t *)&callback;
763 void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
764 int bFailed;
765
766 if( sw_SteamAPI_ManualDispatch_GetAPICallResult( g_hSteamPipe, pCallCompleted->m_hAsyncCall, pTmpCallResult, \
767 pCallCompleted->m_cubParam, pCallCompleted->m_iCallback, &bFailed ) ){
768
769 // Dispatch the call result to the registered handler(s) for the
770 // call identified by pCallCompleted->m_hAsyncCall
771
772 }
773
774 free( pTmpCallResult );
775
776 } else {
777
778 // Look at callback.m_iCallback to see what kind of callback it is,
779 // and dispatch to appropriate handler(s)
780
781 vg_info( "steamworks_event::callback( %i )\n", callback.m_iCallback );
782
783 void *data = callback.m_pubParam;
784
785 switch( callback.m_iCallback ){
786
787 case SW_CBID_P2PSessionRequest: if( OnP2PSessionRequest ) OnP2PSessionRequest(
788 ((P2PSessionRequest_t *)data)->m_steamIDRemote
789 ); break;
790
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
796 ); break;
797
798 case SW_CBID_P2PSessionConnectFail: if( OnP2PSessionConnectFail ) OnP2PSessionConnectFail(
799 ((P2PSessionConnectFail_t *)data)->m_steamIDRemote,
800 ((P2PSessionConnectFail_t *)data)->m_eP2PSessionError
801 ); break;
802
803 case SW_CBID_GameRichPresenceJoinRequested: if( OnSteamJoinRequest ) OnSteamJoinRequest(
804 ((GameRichPresenceJoinRequested_t *)data)->m_steamIDFriend,
805 ((GameRichPresenceJoinRequested_t *)data)->m_rgchConnect
806 ); break;
807
808 default: break;
809
810 }
811
812 }
813
814 SteamAPI_ManualDispatch_FreeLastCallback( g_hSteamPipe );
815
816 }
817
818 }
819
820 /*______________________________________________________________________________________________________________________________
821
822 NO_STEAM
823 ______________________________________________________________________________________________________________________________*/
824
825 #else // #define NO_STEAM
826 // In case we dont want to spam the steam servers
827
828 char *__str_sw_unlinked = "__NO_STEAMWORKS__";
829
830 #define SW_BLANK_RETURN 0
831
832 #define sw_init( x ) 1
833 #define sw_exit()
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
840
841 #define sw_get_image_size( x, y, z )
842 #define sw_get_image_rgba( x, y, z )
843 #define sw_set_achievement( x )
844
845 #endif
846
847 #endif
848