#include "vg.h"
+/*
+ * TODO: Combine interfaces and stuff here instead of having them in client code
+ */
+
#if defined(__linux__) || defined(__APPLE__)
/*
* The 32-bit version of gcc has the alignment requirement for u64 and double
typedef u64 u64_steamid;
typedef u64 SteamAPICall_t;
+typedef u32 AppId_t;
+const AppId_t k_uAppIdInvalid = 0x0;
+
+typedef u32 DepotId_t;
+const DepotId_t k_uDepotIdInvalid = 0x0;
+
+typedef u32 RTime32;
+
enum { k_iSteamUserCallbacks = 100 };
enum { k_iSteamGameServerCallbacks = 200 };
enum { k_iSteamFriendsCallbacks = 300 };
return &steam_async_trackers[ steam_async_track_count ++ ];
}
+/*
+ * Regular callbacks
+ * =============================================================================
+ */
+
+typedef struct steam_callback_handler steam_callback_handler;
+struct steam_callback_handler
+{
+ u32 callback_id;
+ void (*p_handler)( CallbackMsg_t *msg );
+}
+static steam_callback_handlers[64];
+static u32 steam_callback_handler_count;
+
+static int steam_register_callback( u32 id,
+ void (*p_handler)( CallbackMsg_t *msg ) )
+{
+ if( steam_callback_handler_count == vg_list_size(steam_callback_handlers) )
+ {
+ vg_error( "Too many steam callback handlers registered (%u)\n",
+ steam_callback_handler_count );
+
+ return 0;
+ }
+
+ steam_callback_handler *handler = &steam_callback_handlers[
+ steam_callback_handler_count ++ ];
+
+ handler->p_handler = p_handler;
+ handler->callback_id = id;
+
+ return 1;
+}
+
/*
* Event loop
+ * =============================================================================
*/
HSteamPipe SteamAPI_GetHSteamPipe(void);
HSteamPipe SteamGameServer_GetHSteamPipe(void);
void SteamAPI_ReleaseCurrentThreadMemory(void);
-static void steamworks_event_loop( HSteamPipe pipe,
- void(*callback_handler)(CallbackMsg_t *msg) )
+static void steamworks_process_api_call( HSteamPipe pipe,
+ CallbackMsg_t *callback )
+{
+ SteamAPICallCompleted_t *pCallCompleted =
+ (SteamAPICallCompleted_t *)callback->m_pubParam;
+
+ int bFailed;
+
+ void *temp = alloca( pCallCompleted->m_cubParam );
+
+ if( SteamAPI_ManualDispatch_GetAPICallResult(
+ pipe,
+ pCallCompleted->m_hAsyncCall,
+ temp,
+ pCallCompleted->m_cubParam,
+ pCallCompleted->m_iCallback,
+ &bFailed )
+ )
+ {
+ /*
+ * Dispatch the call result to the registered handler(s) for the
+ * call identified by pCallCompleted->m_hAsyncCall
+ */
+
+ vg_info( "steamworks_event::api_call_completed( %lu )\n",
+ pCallCompleted->m_hAsyncCall );
+
+ int j=0;
+ for( int i=0; i<steam_async_track_count; i++ )
+ {
+ if( steam_async_trackers[j].id != pCallCompleted->m_hAsyncCall )
+ {
+ steam_async_trackers[j ++] = steam_async_trackers[i];
+ }
+ else
+ {
+ steam_async *pasync = &steam_async_trackers[j];
+ pasync->p_handler( temp, pasync->data );
+ }
+ }
+
+ if( steam_async_track_count == j )
+ {
+ vg_error( "No tracker was register for API call\n" );
+ }
+
+ steam_async_track_count = j;
+ }
+ else
+ {
+#if 0
+ typedef enum ESteamAPICallFailure
+ {
+ k_ESteamAPICallFailureNone = -1,
+ k_ESteamAPICallFailureSteamGone = 0,
+ k_ESteamAPICallFailureNetworkFailure = 1,
+ k_ESteamAPICallFailureInvalidHandle = 2,
+ k_ESteamAPICallFailureMismatchedCallback = 3,
+ }
+
+ ESteamAPICallFailure;
+ ESteamAPICallFailure fail_why =
+ SteamAPI_ISteamUtils_GetAPICallFailureReason(
+ steam_api_classes.utils, pCallCompleted->m_hAsyncCall );
+
+ vg_error( "steamworks_event: error getting call result on"
+ "%lu (code %d)\n",
+ pCallCompleted->m_hAsyncCall, fail_why );
+#endif
+ }
+}
+
+static void steamworks_event_loop( HSteamPipe pipe )
{
SteamAPI_ManualDispatch_RunFrame( pipe );
CallbackMsg_t callback;
while( SteamAPI_ManualDispatch_GetNextCallback( pipe, &callback ) )
{
- vg_log( "steamworks_event::callback( %i )\n", callback.m_iCallback );
+ vg_low( "steamworks_event::callback( %i )\n", callback.m_iCallback );
/* Check for dispatching API call results */
if( callback.m_iCallback == k_iSteamAPICallCompleted )
{
- SteamAPICallCompleted_t *pCallCompleted =
- (SteamAPICallCompleted_t *)callback.m_pubParam;
-
- void *pTmpCallResult = malloc( pCallCompleted->m_cubParam );
- int bFailed;
-
- if( SteamAPI_ManualDispatch_GetAPICallResult(
- 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
- */
-
- vg_info( "steamworks_event::api_call_completed( %lu )\n",
- pCallCompleted->m_hAsyncCall );
-
- int j=0;
- for( int i=0; i<steam_async_track_count; i++ )
- {
- if( steam_async_trackers[j].id != pCallCompleted->m_hAsyncCall )
- {
- steam_async_trackers[j ++] = steam_async_trackers[i];
- }
- else
- {
- steam_async *pasync = &steam_async_trackers[j];
- pasync->p_handler( pTmpCallResult, pasync->data );
- }
- }
-
- if( steam_async_track_count == j )
- {
- vg_error( "No tracker was register for API call\n" );
- }
-
- steam_async_track_count = j;
- }
- else
- {
-#if 0
- typedef enum ESteamAPICallFailure
- {
- k_ESteamAPICallFailureNone = -1,
- k_ESteamAPICallFailureSteamGone = 0,
- k_ESteamAPICallFailureNetworkFailure = 1,
- k_ESteamAPICallFailureInvalidHandle = 2,
- k_ESteamAPICallFailureMismatchedCallback = 3,
- }
-
- ESteamAPICallFailure;
- ESteamAPICallFailure fail_why =
- SteamAPI_ISteamUtils_GetAPICallFailureReason(
- steam_api_classes.utils, pCallCompleted->m_hAsyncCall );
-
- vg_error( "steamworks_event: error getting call result on"
- "%lu (code %d)\n",
- pCallCompleted->m_hAsyncCall, fail_why );
-#endif
- }
-
- free( pTmpCallResult );
+ steamworks_process_api_call( pipe, &callback );
}
else
{
* void *data = callback.m_pubParam;
*/
- callback_handler(&callback);
+ for( int i=0; i<steam_callback_handler_count; i++ )
+ {
+ steam_callback_handler *handler = &steam_callback_handlers[i];
+ if( handler->callback_id == callback.m_iCallback )
+ {
+ handler->p_handler( &callback );
+ break;
+ }
+ }
}
SteamAPI_ManualDispatch_FreeLastCallback( pipe );
}
}
+/*
+ * This is required to run the server outside of steamcmd environment.
+ * It can be any appid but idealy the one that is actually your game
+ */
+static void steamworks_ensure_txt( const char *appid_str )
+{
+ FILE *txt = fopen("steam_appid.txt", "w");
+ fputs( appid_str, txt );
+ fclose( txt );
+}
+
#endif /* VG_STEAM_H */