fov slider input maps menu stuff
[carveJwlIkooP6JGAAIwe30JlM.git] / steam.h
1 /*
2 * Copyright (C) 2021-2022 Mt.ZERO Software, Harry Godden - All Rights Reserved
3 * All trademarks are property of their respective owners
4 */
5
6 #ifndef STEAM_H
7 #define STEAM_H
8
9 #include "vg/vg_steam.h"
10 #include "vg/vg_steam_utils.h"
11 #include "vg/vg_steam_networking.h"
12 #include "vg/vg_steam_auth.h"
13 #include "vg/vg_steam_http.h"
14 #include "vg/vg_steam_friends.h"
15 #include "vg/vg_steam_user_stats.h"
16
17 /*
18 * We only want to use steamworks if building for the networked version,
19 * theres not much point otherwise. We mainly want steamworks for setting
20 * achievements etc.. so that includes our own server too.
21 *
22 * This file also wraps the functions and interfaces that we want to use to
23 * make them a bit easier to read, since they are the flat API they have very
24 * long names. in non-networked builds they will return default errors or do
25 * nothing.
26 */
27
28 VG_STATIC char steam_username_at_startup[128];
29
30 VG_STATIC void recv_steam_warning( int severity, const char *msg )
31 {
32 if( severity == 0 )
33 vg_low( "%s\n", msg );
34 else
35 vg_info( "%s\n", msg );
36 }
37
38 VG_STATIC int steam_ready = 0,
39 steam_stats_ready = 0;
40
41 VG_STATIC void *hSteamNetworkingSockets,
42 *hSteamUser;
43
44 VG_STATIC ISteamUserStats *hSteamUserStats;
45 VG_STATIC HSteamPipe hSteamClientPipe;
46
47 VG_STATIC const char *steam_achievement_names[] =
48 {
49 "ALBERT", "MARC",
50 "ROUTE_MPY", "ROUTE_MPG", "ROUTE_MPB", "ROUTE_MPR",
51 "ROUTE_TO", "ROUTE_TC"
52 };
53
54 VG_STATIC void steam_store_achievements(void)
55 {
56 if( steam_ready && steam_stats_ready )
57 {
58 SteamAPI_ISteamUserStats_StoreStats( hSteamUserStats );
59 }
60 }
61
62 VG_STATIC void steam_set_achievement( const char *name )
63 {
64 if( steam_ready && steam_stats_ready )
65 {
66 if( SteamAPI_ISteamUserStats_SetAchievement( hSteamUserStats, name ) )
67 {
68 vg_success( "Achievement set! '%s'\n", name );
69 }
70 else
71 {
72 vg_warn( "Failed to set achievement: %s\n", name );
73 }
74 }
75 else
76 {
77 vg_warn( "Failed to set achievement (steam not ready): %s\n", name );
78 }
79 }
80
81 VG_STATIC void steam_clear_achievement( const char *name )
82 {
83 if( steam_ready && steam_stats_ready )
84 {
85 if( SteamAPI_ISteamUserStats_ClearAchievement( hSteamUserStats, name ) )
86 {
87 vg_info( "Achievement cleared: '%s'\n", name );
88 }
89 else
90 {
91 vg_warn( "Failed to clear achievement: %s\n", name );
92 }
93 }
94 else
95 {
96 vg_warn( "Failed to clear achievement (steam not ready): %s\n", name );
97 }
98 }
99
100
101 VG_STATIC int steam_list_achievements( int argc, char const *argv[] )
102 {
103 vg_info( "Achievements: \n" );
104
105 if( steam_ready && steam_stats_ready )
106 {
107 for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
108 {
109 int set = 0;
110 const char *name = steam_achievement_names[i];
111
112 if( SteamAPI_ISteamUserStats_GetAchievement(
113 hSteamUserStats, name, &set ) )
114 {
115 vg_info( " %s %s\n", (set? "[YES]": "[ ]"), name );
116 }
117 else
118 {
119 vg_warn( " Error while fetching achievement status '%s'\n", name );
120 }
121 }
122 }
123 else
124 {
125 vg_warn( " Steam is not initialized, no results\n" );
126 }
127
128 return 0;
129 }
130
131 VG_STATIC int steam_clear_all_achievements( int argc, char const *argv[] )
132 {
133 if( steam_ready && steam_stats_ready )
134 {
135 for( int i=0; i<vg_list_size(steam_achievement_names); i++ )
136 {
137 steam_clear_achievement( steam_achievement_names[i] );
138 }
139
140 steam_store_achievements();
141 }
142 else
143 {
144 vg_warn( "steam is not initialized, cannot clear\n" );
145 }
146
147 return 0;
148 }
149
150 VG_STATIC int steam_set_achievemnt_test( int argc, char const *argv[] )
151 {
152 if( argc < 2 )
153 return 0;
154
155 if( strcmp( argv[0], "monkey_island" ) )
156 return 0;
157
158 steam_set_achievement( argv[1] );
159 steam_store_achievements();
160
161 return 0;
162 }
163
164 VG_STATIC void steam_on_recieve_current_stats( CallbackMsg_t *msg )
165 {
166 UserStatsReceived_t *rec = (UserStatsReceived_t *)msg->m_pubParam;
167
168 if( rec->m_eResult == k_EResultOK )
169 {
170 vg_info( "Recieved stats for: %lu (user: %lu)\n", rec->m_nGameID,
171 rec->m_steamIDUser );
172 steam_stats_ready = 1;
173 }
174 else
175 {
176 vg_error( "Error recieveing stats for user (%u)\n", rec->m_eResult );
177 }
178 }
179
180 VG_STATIC ISteamInput *steam_hInput;
181
182 VG_STATIC int steam_init(void)
183 {
184 const char *username = NULL;
185
186 #ifdef SR_NETWORKED
187 vg_info( "Initializing steamworks\n" );
188
189 if( !SteamAPI_Init() )
190 {
191 printf("\n");
192 vg_error( "Steamworks failed to initialize\n" );
193 return 1;
194 }
195
196 steam_ready = 1;
197
198 SteamAPI_ManualDispatch_Init();
199
200 /* Connect interfaces */
201 hSteamClientPipe = SteamAPI_GetHSteamPipe();
202 hSteamNetworkingSockets = SteamAPI_SteamNetworkingSockets_SteamAPI();
203 hSteamUser = SteamAPI_SteamUser();
204
205 ISteamUtils *utils = SteamAPI_SteamUtils();
206 SteamAPI_ISteamUtils_SetWarningMessageHook( utils, recv_steam_warning );
207
208 printf("\n");
209 vg_success( "\nSteamworks API running\n" );
210
211 ISteamFriends *hSteamFriends = SteamAPI_SteamFriends();
212 username = SteamAPI_ISteamFriends_GetPersonaName( hSteamFriends );
213
214 /*
215 * Request stats
216 * --------------------------------------------------------
217 */
218 hSteamUserStats = SteamAPI_SteamUserStats();
219
220 steam_register_callback( k_iUserStatsReceived,
221 steam_on_recieve_current_stats );
222
223 if( !SteamAPI_ISteamUserStats_RequestCurrentStats( hSteamUserStats ) )
224 vg_warn( "No Steam Logon: Cannot request stats\n" );
225
226
227 vg_function_push( (struct vg_cmd)
228 {
229 .name = "ach_list",
230 .function = steam_list_achievements
231 });
232
233 vg_function_push( (struct vg_cmd)
234 {
235 .name = "ach_clear_all",
236 .function = steam_clear_all_achievements
237 });
238
239 vg_function_push( (struct vg_cmd)
240 {
241 .name = "ach_set",
242 .function = steam_set_achievemnt_test
243 });
244
245 steam_hInput = SteamAPI_SteamInput();
246 SteamAPI_ISteamInput_Init( steam_hInput, 0 );
247 SteamAPI_ISteamInput_RunFrame( steam_hInput, 0 );
248
249 #endif
250
251 /* TODO: On username update callback */
252 str_utf8_collapse( username, steam_username_at_startup,
253 vg_list_size(steam_username_at_startup) );
254
255 return 1;
256 }
257
258 VG_STATIC void steam_update(void)
259 {
260 if( steam_ready )
261 {
262 steamworks_event_loop( hSteamClientPipe );
263
264 if( steam_hInput )
265 {
266 SteamAPI_ISteamInput_RunFrame( steam_hInput, 0 );
267
268 InputHandle_t joy0 = SteamAPI_ISteamInput_GetControllerForGamepadIndex(
269 steam_hInput, 0 );
270
271 vg.gamepad_use_trackpad_look = 0;
272 if( joy0 != 0 )
273 {
274 ESteamInputType type = SteamAPI_ISteamInput_GetInputTypeForHandle(
275 steam_hInput, joy0 );
276
277 if( type == k_ESteamInputType_SteamController )
278 {
279 vg.gamepad_use_trackpad_look = 1;
280 menu_display_controller = k_menu_controller_type_steam;
281 }
282 else if( type == k_ESteamInputType_SteamDeckController )
283 {
284 menu_display_controller = k_menu_controller_type_steam_deck;
285 }
286 else if( type == k_ESteamInputType_PS3Controller ||
287 type == k_ESteamInputType_PS4Controller ||
288 type == k_ESteamInputType_PS5Controller )
289 {
290 menu_display_controller = k_menu_controller_type_playstation;
291 }
292 else if( type == k_ESteamInputType_XBox360Controller ||
293 type == k_ESteamInputType_XBoxOneController )
294 {
295 menu_display_controller = k_menu_controller_type_xbox;
296 }
297 else
298 {
299 /* currently unsupported controller */
300 menu_display_controller = k_menu_controller_type_xbox;
301 }
302 }
303 else
304 menu_display_controller = k_menu_controller_type_keyboard;
305 }
306 }
307 }
308
309 VG_STATIC void steam_end(void *nothing)
310 {
311 if( steam_ready )
312 {
313 vg_info( "Shutting down\n..." );
314 SteamAPI_Shutdown();
315 }
316 }
317
318 #endif /* STEAM_H */