get achievements working again
[fishladder.git] / vg / vg_steamworks.h
1 #if defined(__linux__) || defined(__APPLE__)
2 // The 32-bit version of gcc has the alignment requirement for uint64 and double set to
3 // 4 meaning that even with #pragma pack(8) these types will only be four-byte aligned.
4 // The 64-bit version of gcc has the alignment requirement for these types set to
5 // 8 meaning that unless we use #pragma pack(4) our structures will get bigger.
6 // The 64-bit structure packing has to match the 32-bit structure packing for each platform.
7 #define VALVE_CALLBACK_PACK_SMALL
8 #else
9 #define VALVE_CALLBACK_PACK_LARGE
10 #endif
11
12 #if defined( VALVE_CALLBACK_PACK_SMALL )
13 #pragma pack( push, 4 )
14 #elif defined( VALVE_CALLBACK_PACK_LARGE )
15 #pragma pack( push, 8 )
16 #else
17 #error steam_api_common.h should define VALVE_CALLBACK_PACK_xxx
18 #endif
19
20 // Types
21 typedef void ISteamFriends;
22 typedef void ISteamUserStats;
23 typedef void ISteamUtils;
24 typedef void ISteamUser;
25 typedef void ISteamNetworking;
26
27 typedef i32 HSteamPipe;
28 typedef i32 HSteamUser;
29
30 typedef int E_iCallBack_t;
31
32 typedef u32 SNetSocket_t; // CreateP2PConnectionSocket()
33 typedef u32 SNetListenSocket_t; // CreateListenSocket()
34
35 typedef u64 uint64_steamid;
36 typedef u64 SteamAPICall_t;
37
38 enum { k_iSteamUserCallbacks = 100 };
39 enum { k_iSteamGameServerCallbacks = 200 };
40 enum { k_iSteamFriendsCallbacks = 300 };
41 enum { k_iSteamBillingCallbacks = 400 };
42 enum { k_iSteamMatchmakingCallbacks = 500 };
43 enum { k_iSteamContentServerCallbacks = 600 };
44 enum { k_iSteamUtilsCallbacks = 700 };
45 enum { k_iClientFriendsCallbacks = 800 };
46 enum { k_iClientUserCallbacks = 900 };
47 enum { k_iSteamAppsCallbacks = 1000 };
48 enum { k_iSteamUserStatsCallbacks = 1100 };
49 enum { k_iSteamNetworkingCallbacks = 1200 };
50 enum { k_iSteamNetworkingSocketsCallbacks = 1220 };
51 enum { k_iSteamNetworkingMessagesCallbacks = 1250 };
52 enum { k_iSteamNetworkingUtilsCallbacks = 1280 };
53 enum { k_iClientRemoteStorageCallbacks = 1300 };
54 enum { k_iClientDepotBuilderCallbacks = 1400 };
55 enum { k_iSteamGameServerItemsCallbacks = 1500 };
56 enum { k_iClientUtilsCallbacks = 1600 };
57 enum { k_iSteamGameCoordinatorCallbacks = 1700 };
58 enum { k_iSteamGameServerStatsCallbacks = 1800 };
59 enum { k_iSteam2AsyncCallbacks = 1900 };
60 enum { k_iSteamGameStatsCallbacks = 2000 };
61 enum { k_iClientHTTPCallbacks = 2100 };
62 enum { k_iClientScreenshotsCallbacks = 2200 };
63 enum { k_iSteamScreenshotsCallbacks = 2300 };
64 enum { k_iClientAudioCallbacks = 2400 };
65 enum { k_iClientUnifiedMessagesCallbacks = 2500 };
66 enum { k_iSteamStreamLauncherCallbacks = 2600 };
67 enum { k_iClientControllerCallbacks = 2700 };
68 enum { k_iSteamControllerCallbacks = 2800 };
69 enum { k_iClientParentalSettingsCallbacks = 2900 };
70 enum { k_iClientDeviceAuthCallbacks = 3000 };
71 enum { k_iClientNetworkDeviceManagerCallbacks = 3100 };
72 enum { k_iClientMusicCallbacks = 3200 };
73 enum { k_iClientRemoteClientManagerCallbacks = 3300 };
74 enum { k_iClientUGCCallbacks = 3400 };
75 enum { k_iSteamStreamClientCallbacks = 3500 };
76 enum { k_IClientProductBuilderCallbacks = 3600 };
77 enum { k_iClientShortcutsCallbacks = 3700 };
78 enum { k_iClientRemoteControlManagerCallbacks = 3800 };
79 enum { k_iSteamAppListCallbacks = 3900 };
80 enum { k_iSteamMusicCallbacks = 4000 };
81 enum { k_iSteamMusicRemoteCallbacks = 4100 };
82 enum { k_iClientVRCallbacks = 4200 };
83 enum { k_iClientGameNotificationCallbacks = 4300 };
84 enum { k_iSteamGameNotificationCallbacks = 4400 };
85 enum { k_iSteamHTMLSurfaceCallbacks = 4500 };
86 enum { k_iClientVideoCallbacks = 4600 };
87 enum { k_iClientInventoryCallbacks = 4700 };
88 enum { k_iClientBluetoothManagerCallbacks = 4800 };
89 enum { k_iClientSharedConnectionCallbacks = 4900 };
90 enum { k_ISteamParentalSettingsCallbacks = 5000 };
91 enum { k_iClientShaderCallbacks = 5100 };
92 enum { k_iSteamGameSearchCallbacks = 5200 };
93 enum { k_iSteamPartiesCallbacks = 5300 };
94 enum { k_iClientPartiesCallbacks = 5400 };
95 enum { k_iSteamSTARCallbacks = 5500 };
96 enum { k_iClientSTARCallbacks = 5600 };
97 enum { k_iSteamRemotePlayCallbacks = 5700 };
98 enum { k_iClientCompatCallbacks = 5800 };
99 enum { k_iSteamChatCallbacks = 5900 };
100
101 // Structures
102 typedef struct {
103 u32 m_u32;
104 u64 m_u64;
105 u16 m_u16;
106 double m_d;
107 } ValvePackingSentinel_t;
108
109 typedef struct {
110
111 HSteamUser m_hSteamUser; // Specific user to whom this callback applies.
112 int m_iCallback; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
113 uint8_t *m_pubParam; // Points to the callback structure
114 int m_cubParam; // Size of the data pointed to by m_pubParam
115
116 } CallbackMsg_t;
117
118 typedef struct {
119
120 SteamAPICall_t m_hAsyncCall;
121 int m_iCallback;
122 u32 m_cubParam;
123
124 } SteamAPICallCompleted_t;
125 #define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
126
127
128 #pragma pack( pop )
129
130 // API
131 void SteamAPI_Shutdown();
132 int SteamAPI_Init();
133 int SteamAPI_RestartAppIfNecessary( u32 unOwnAppID );
134
135 void SteamAPI_ManualDispatch_Init();
136 void SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
137 int SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, CallbackMsg_t *pCallbackMsg );
138 void SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
139 int SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, int *pbFailed );
140 void SteamAPI_ReleaseCurrentThreadMemory();
141
142 int SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const char *pchName );
143
144 HSteamPipe SteamAPI_GetHSteamPipe();
145 HSteamUser SteamAPI_GetHSteamUser();
146
147 struct
148 {
149 ISteamFriends *friends;
150 ISteamUser *user;
151 ISteamUserStats *stats;
152 ISteamNetworking *net;
153
154 HSteamPipe pipe;
155 } steam_api_classes;
156
157 ISteamFriends *SteamAPI_SteamFriends_v017();
158 ISteamUser *SteamAPI_SteamUser_v021();
159 ISteamUserStats *SteamAPI_SteamUserStats_v012();
160 ISteamNetworking *SteamAPI_SteamNetworking_v006();
161
162 static void sw_exit(void)
163 {
164 SteamAPI_Shutdown();
165 }
166
167 static int sw_init(void)
168 {
169 #if defined(VALVE_CALLBACK_PACK_SMALL)
170 if( sizeof(ValvePackingSentinel_t) != 24 ){
171 printf( "Struct packing error: ValvePackingSentinel_t expected 24 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
172 return 0;
173 }
174 #else
175 if( sizeof(ValvePackingSentinel_t) != 32 ){
176 printf( "Struct packing error: ValvePackingSentinel_t expected 32 got %i\nThe application is built incorrectly\n", (int)sizeof(ValvePackingSentinel_t));
177 return 0;
178 }
179 #endif
180
181 vg_info( "Intializing steamworks\n" );
182
183 if( SteamAPI_RestartAppIfNecessary( VG_STEAM_APPID ) == 1 )
184 {
185 vg_info( "Restarting app via steam\n" );
186 return 0;
187 }
188
189 if( !SteamAPI_Init() )
190 {
191 vg_error( "Steamworks connection failed\n" );
192 return 0;
193 }
194
195 SteamAPI_ManualDispatch_Init();
196
197 steam_api_classes.friends = SteamAPI_SteamFriends_v017();
198 steam_api_classes.user = SteamAPI_SteamUser_v021();
199 steam_api_classes.stats = SteamAPI_SteamUserStats_v012();
200 steam_api_classes.net = SteamAPI_SteamNetworking_v006();
201
202 if( !steam_api_classes.friends || !steam_api_classes.user || !steam_api_classes.stats || !steam_api_classes.net )
203 {
204 vg_error( "Steamworks interface pointers failed. Steamworks DLL may be old\n" );
205 SteamAPI_Shutdown();
206 return 0;
207 }
208
209 steam_api_classes.pipe = SteamAPI_GetHSteamPipe();
210 vg_success( "Steamworks API running\n" );
211
212 vg_register_exit( &sw_exit, "SteamAPI" );
213 return 1;
214 }
215
216 static void sw_event_loop(void)
217 {
218 SteamAPI_ManualDispatch_RunFrame( steam_api_classes.pipe );
219 CallbackMsg_t callback;
220
221 while( SteamAPI_ManualDispatch_GetNextCallback( steam_api_classes.pipe, &callback ) )
222 {
223 // Check for dispatching API call results
224 if( callback.m_iCallback == SW_CBID_SteamAPICallCompleted ){
225
226 SteamAPICallCompleted_t *pCallCompleted = (SteamAPICallCompleted_t *)&callback;
227 void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
228 int bFailed;
229
230 if( SteamAPI_ManualDispatch_GetAPICallResult(
231 steam_api_classes.pipe,
232 pCallCompleted->m_hAsyncCall,
233 pTmpCallResult,
234 pCallCompleted->m_cubParam,
235 pCallCompleted->m_iCallback,
236 &bFailed )
237 )
238 {
239 // Dispatch the call result to the registered handler(s) for the
240 // call identified by pCallCompleted->m_hAsyncCall
241 }
242
243 free( pTmpCallResult );
244 }
245 else
246 {
247 // Look at callback.m_iCallback to see what kind of callback it is,
248 // and dispatch to appropriate handler(s)
249
250 vg_info( "steamworks_event::callback( %i )\n", callback.m_iCallback );
251
252 //void *data = callback.m_pubParam;
253
254 switch( callback.m_iCallback )
255 {
256 default: break;
257 }
258 }
259
260 SteamAPI_ManualDispatch_FreeLastCallback( steam_api_classes.pipe );
261 }
262 }
263
264 static void sw_set_achievement( const char *vg_ach_name )
265 {
266 struct vg_achievement *ach = NULL;
267
268 for( int i = 0; i < vg_list_size( vg_achievements ); i ++ )
269 if( !strcmp( vg_ach_name, vg_achievements[i].name ) )
270 ach = &vg_achievements[i];
271
272 if( !ach->is_set )
273 {
274 SteamAPI_ISteamUserStats_SetAchievement( steam_api_classes.stats, vg_ach_name );
275 ach->is_set = 1;
276 vg_success( "Achievement set: '%s'\n", vg_ach_name );
277 }
278 }