bad char
[vg.git] / vg_steam.h
index 01c448acf076f6ae33826c91b85d479768b9fd3a..db0e84dca4de676042c25f54ff776ce9a3aee5bd 100644 (file)
-#ifndef VG_STEAM_H
-#define VG_STEAM_H
-
-#include "vg.h"
-#include "vg_log.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 
- * set to 4 meaning that even with #pragma pack(8) these types will only be 
- * four-byte aligned. The 64-bit version of gcc has the alignment requirement 
- * for these types set to 8 meaning that unless we use #pragma pack(4) our 
- * structures will get bigger. The 64-bit structure packing has to match the 
- * 32-bit structure packing for each platform.
- */
- #define VALVE_CALLBACK_PACK_SMALL
-;
- #pragma pack( push, 4 )
-#else
- #define VALVE_CALLBACK_PACK_LARGE
- #pragma pack( push, 8 )
-#endif
-
-typedef i32    HSteamPipe;
-typedef i32    HSteamUser;
-
-typedef int E_iCallBack_t;
-
-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;
-typedef u32 AccountID_t;
-
-enum { k_iSteamUserCallbacks = 100 };
-enum { k_iSteamGameServerCallbacks = 200 };
-enum { k_iSteamFriendsCallbacks = 300 };
-enum { k_iSteamBillingCallbacks = 400 };
-enum { k_iSteamMatchmakingCallbacks = 500 };
-enum { k_iSteamContentServerCallbacks = 600 };
-enum { k_iSteamUtilsCallbacks = 700 };
-enum { k_iClientFriendsCallbacks = 800 };
-enum { k_iClientUserCallbacks = 900 };
-enum { k_iSteamAppsCallbacks = 1000 };
-enum { k_iSteamUserStatsCallbacks = 1100 };
-enum { k_iSteamNetworkingCallbacks = 1200 };
-enum { k_iSteamNetworkingSocketsCallbacks = 1220 };
-enum { k_iSteamNetworkingMessagesCallbacks = 1250 };
-enum { k_iSteamNetworkingUtilsCallbacks = 1280 };
-enum { k_iSteamRemoteStorageCallbacks = 1300 };
-enum { k_iClientDepotBuilderCallbacks = 1400 };
-enum { k_iSteamGameServerItemsCallbacks = 1500 };
-enum { k_iClientUtilsCallbacks = 1600 };
-enum { k_iSteamGameCoordinatorCallbacks = 1700 };
-enum { k_iSteamGameServerStatsCallbacks = 1800 };
-enum { k_iSteam2AsyncCallbacks = 1900 };
-enum { k_iSteamGameStatsCallbacks = 2000 };
-enum { k_iClientHTTPCallbacks = 2100 };
-enum { k_iClientScreenshotsCallbacks = 2200 };
-enum { k_iSteamScreenshotsCallbacks = 2300 };
-enum { k_iClientAudioCallbacks = 2400 };
-enum { k_iClientUnifiedMessagesCallbacks = 2500 };
-enum { k_iSteamStreamLauncherCallbacks = 2600 };
-enum { k_iClientControllerCallbacks = 2700 };
-enum { k_iSteamControllerCallbacks = 2800 };
-enum { k_iClientParentalSettingsCallbacks = 2900 };
-enum { k_iClientDeviceAuthCallbacks = 3000 };
-enum { k_iClientNetworkDeviceManagerCallbacks = 3100 };
-enum { k_iClientMusicCallbacks = 3200 };
-enum { k_iClientRemoteClientManagerCallbacks = 3300 };
-enum { k_iClientUGCCallbacks = 3400 };
-enum { k_iSteamUGCCallbacks = 3400 };
-enum { k_iSteamStreamClientCallbacks = 3500 };
-enum { k_IClientProductBuilderCallbacks = 3600 };
-enum { k_iClientShortcutsCallbacks = 3700 };
-enum { k_iClientRemoteControlManagerCallbacks = 3800 };
-enum { k_iSteamAppListCallbacks = 3900 };
-enum { k_iSteamMusicCallbacks = 4000 };
-enum { k_iSteamMusicRemoteCallbacks = 4100 };
-enum { k_iClientVRCallbacks = 4200 };
-enum { k_iClientGameNotificationCallbacks = 4300 }; 
-enum { k_iSteamGameNotificationCallbacks = 4400 }; 
-enum { k_iSteamHTMLSurfaceCallbacks = 4500 };
-enum { k_iClientVideoCallbacks = 4600 };
-enum { k_iClientInventoryCallbacks = 4700 };
-enum { k_iClientBluetoothManagerCallbacks = 4800 };
-enum { k_iClientSharedConnectionCallbacks = 4900 };
-enum { k_ISteamParentalSettingsCallbacks = 5000 };
-enum { k_iClientShaderCallbacks = 5100 };
-enum { k_iSteamGameSearchCallbacks = 5200 };
-enum { k_iSteamPartiesCallbacks = 5300 };
-enum { k_iClientPartiesCallbacks = 5400 };
-enum { k_iSteamSTARCallbacks = 5500 };
-enum { k_iClientSTARCallbacks = 5600 };
-enum { k_iSteamRemotePlayCallbacks = 5700 };
-enum { k_iClientCompatCallbacks = 5800 };
-enum { k_iSteamChatCallbacks = 5900 };
-
-// General result codes
-typedef enum EResult
-{
-       k_EResultNone = 0,                                      // no result
-       k_EResultOK     = 1,                                            // success
-       k_EResultFail = 2,                                      // generic failure 
-       k_EResultNoConnection = 3,                      // no/failed network connection
-//     k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
-       k_EResultInvalidPassword = 5,           // password/ticket is invalid
-       k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
-       k_EResultInvalidProtocolVer = 7,        // protocol version is incorrect
-       k_EResultInvalidParam = 8,                      // a parameter is incorrect
-       k_EResultFileNotFound = 9,                      // file was not found
-       k_EResultBusy = 10,                                     // called method busy - action not taken
-       k_EResultInvalidState = 11,             // called object was in an invalid state
-       k_EResultInvalidName = 12,                 // name is invalid
-       k_EResultInvalidEmail = 13,             // email is invalid
-       k_EResultDuplicateName = 14,            // name is not unique
-       k_EResultAccessDenied = 15,             // access is denied
-       k_EResultTimeout = 16,                     // operation timed out
-       k_EResultBanned = 17,                           // VAC2 banned
-       k_EResultAccountNotFound = 18,  // account not found
-       k_EResultInvalidSteamID = 19,           // steamID is invalid
-       k_EResultServiceUnavailable = 20,// The requested service is currently 
-                                    // unavailable
-       k_EResultNotLoggedOn = 21,       // The user is not logged on
-       k_EResultPending = 22,                          // Request is pending (may be in process, or
-                                    // waiting on third party)
-       k_EResultEncryptionFailure = 23,                // Encryption or Decryption failed
-       k_EResultInsufficientPrivilege = 24,// Insufficient privilege
-       k_EResultLimitExceeded = 25,                    // Too much of a good thing
-       k_EResultRevoked = 26,                          // Access has been revoked (used for revoked
-                                    // guest passes)
-       k_EResultExpired = 27,                          // License/Guest pass the user is trying to 
-                                    // access is expired
-       k_EResultAlreadyRedeemed = 28,  // Guest pass has already been redeemed by 
-                                    // account, cannot be acked again
-       k_EResultDuplicateRequest = 29, // The request is a duplicate and the action
-                                    // has already occurred in the past, ignored
-                                    // this time
-       k_EResultAlreadyOwned = 30,             // All the games in this guest pass 
-                                    // redemption request are already owned by 
-                                    // the user
-       k_EResultIPNotFound = 31,                       // IP address not found
-       k_EResultPersistFailed = 32,            // failed to write change to the data store
-       k_EResultLockingFailed = 33,            // failed to acquire access lock for this 
-                                    // operation
-       k_EResultLogonSessionReplaced = 34,
-       k_EResultConnectFailed = 35,
-       k_EResultHandshakeFailed = 36,
-       k_EResultIOFailure = 37,
-       k_EResultRemoteDisconnect = 38,
-       k_EResultShoppingCartNotFound = 39,     // failed to find the shopping cart 
-                                       // requested
-       k_EResultBlocked = 40,                                  // a user didn't allow it
-       k_EResultIgnored = 41,                                  // target is ignoring sender
-       k_EResultNoMatch = 42,                                  // nothing matching the request found
-       k_EResultAccountDisabled = 43,
-       k_EResultServiceReadOnly = 44,          // this service is not accepting content 
-                                       // changes right now
-       k_EResultAccountNotFeatured = 45,       // account doesn't have value, so this 
-                                       // feature isn't available
-       k_EResultAdministratorOK = 46,          // allowed to take this action, but only 
-                                       // because requester is admin
-       k_EResultContentVersion = 47,                   // A Version mismatch in content 
-                                       // transmitted within the Steam protocol.
-       k_EResultTryAnotherCM = 48,                     // The current CM can't service the user 
-                                       // making a request, user should try 
-                                       // another.
-       k_EResultPasswordRequiredToKickSession = 49, // You are already logged in 
-                                       // elsewhere, this cached credential 
-                                       // login has failed.
-       k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in 
-                                           // elsewhere, you must wait
-       k_EResultSuspended = 51,   // Long running operation (content download) 
-                              // suspended/paused
-       k_EResultCancelled = 52,   // Operation canceled (typically by user: 
-                              // content download)
-       k_EResultDataCorruption = 53,   // Operation canceled because data is ill 
-                                 // formed or unrecoverable
-       k_EResultDiskFull = 54,                 // Operation canceled - not enough disk space.
-       k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
-       k_EResultPasswordUnset = 56,            // Password could not be verified as it's 
-                                    // unset server side
-       k_EResultExternalAccountUnlinked = 57,  // External account (PSN, Facebook...)
-                                          // is not linked to a Steam account
-       k_EResultPSNTicketInvalid = 58,                 // PSN ticket was invalid
-       k_EResultExternalAccountAlreadyLinked = 59,     // External account (PSN, 
-         // Facebook...) is already linked to some other account, 
-         // must explicitly request to replace/delete the link first
-       k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict
-                                     // between the local and remote files
-       k_EResultIllegalPassword = 61,   // The requested new password is not legal
-       k_EResultSameAsPreviousValue = 62,// new value is the same as the old one ( 
-                                     // secret question and answer )
-       k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor 
-                                     // authentication failure
-       k_EResultCannotUseOldPassword = 64,     // The requested new password is not 
-                                       // legal
-       k_EResultInvalidLoginAuthCode = 65,     // account login denied due to auth code 
-                                       // invalid
-       k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd 
-                                           // factor auth failure - and no mail 
-                                           // has been sent
-       k_EResultHardwareNotCapableOfIPT = 67,
-       k_EResultIPTInitError = 68,
-       k_EResultParentalControlRestricted = 69,// operation failed due to parental 
-                                           // control restrictions for current 
-                                           // user
-       k_EResultFacebookQueryError = 70,                // Facebook query returned an error
-       k_EResultExpiredLoginAuthCode = 71,              // account login denied due to auth 
-                                           // code expired
-       k_EResultIPLoginRestrictionFailed = 72,
-       k_EResultAccountLockedDown = 73,
-       k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
-       k_EResultNoMatchingURL = 75,
-       k_EResultBadResponse = 76,              // parse failure, missing field, etc.
-       k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action 
-                                         // until they re-enter their password
-       k_EResultValueOutOfRange = 78,  // the value entered is outside the 
-                                    // acceptable range
-       k_EResultUnexpectedError = 79,  // something happened that we didn't expect
-                                    // to ever happen
-       k_EResultDisabled = 80,                         // The requested service has been configured
-                                    // to be unavailable
-       k_EResultInvalidCEGSubmission = 81,     // The set of files submitted to the CEG 
-                                       // server are not valid !
-       k_EResultRestrictedDevice = 82,         // The device being used is not allowed 
-                                       // to perform this action
-       k_EResultRegionLocked = 83,                     // The action could not be complete 
-                                       // because it is region restricted
-       k_EResultRateLimitExceeded = 84,        // Temporary rate limit exceeded, try 
-                                    // again later, different from 
-                                    // k_EResultLimitExceeded which may be 
-                                    // permanent
-       k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to 
-                                                  // login
-       k_EResultItemDeleted = 86,      // The thing we're trying to access has been 
-                              // deleted
-       k_EResultAccountLoginDeniedThrottle = 87,       // login attempt failed, try to 
-                                             // throttle response to possible 
-                                             // attacker
-       k_EResultTwoFactorCodeMismatch = 88,            // two factor code mismatch
-       k_EResultTwoFactorActivationCodeMismatch = 89,  // activation code for 
-                                                   // two-factor didn't match
-       k_EResultAccountAssociatedToMultiplePartners = 90,      // account has been 
-                                          // associated with multiple partners
-       k_EResultNotModified = 91,                                      // data not modified
-       k_EResultNoMobileDevice = 92,   // the account does not have a mobile 
-                                 // device associated with it
-       k_EResultTimeNotSynced = 93,    // the time presented is out of range or 
-                                 // tolerance
-       k_EResultSmsCodeFailed = 94,    // SMS code failure (no match, none pending, 
-                                 // etc.)
-       k_EResultAccountLimitExceeded = 95,     // Too many accounts access this resource
-       k_EResultAccountActivityLimitExceeded = 96,// Too many changes to 
-                                              // this account
-       k_EResultPhoneActivityLimitExceeded = 97,       // Too many changes to this phone
-       k_EResultRefundToWallet = 98,   // Cannot refund to payment method, must use 
-                                 // wallet
-       k_EResultEmailSendFailure = 99, // Cannot send an email
-       k_EResultNotSettled = 100,      // Can't perform operation till payment 
-                              // has settled
-       k_EResultNeedCaptcha = 101,// Needs to provide a valid captcha
-       k_EResultGSLTDenied = 102,      // a game server login token owned by this token's
-                              // owner has been banned
-       k_EResultGSOwnerDenied = 103,   // game server owner is denied for other reason
-                        // (account lock, community ban, vac ban, missing phone)
-       k_EResultInvalidItemType = 104,// the type of thing we were requested to act 
-                                  // on is invalid
-       k_EResultIPBanned = 105,// the ip address has been banned from taking this 
-                           // action
-       k_EResultGSLTExpired = 106,// this token has expired from disuse; can be 
-                              // reset for use
-       k_EResultInsufficientFunds = 107,// user doesn't have enough wallet funds to 
-                                    // complete the action
-       k_EResultTooManyPending = 108,  // There are too many of this thing pending 
-                                    // already
-       k_EResultNoSiteLicensesFound = 109,     // No site licenses found
-       k_EResultWGNetworkSendExceeded = 110,// the WG couldn't send a response
-                              // because we exceeded max network send size
-       k_EResultAccountNotFriends = 111, // the user is not mutually friends
-       k_EResultLimitedUserAccount = 112,// the user is limited
-       k_EResultCantRemoveItem = 113,   // item can't be removed
-       k_EResultAccountDeleted = 114,   // account has been deleted
-       k_EResultExistingUserCancelledLicense = 115,    
-   // A license for this already exists, but cancelled
-       k_EResultCommunityCooldown = 116,       // access is denied because of a 
-            // community cooldown (probably from support profile data resets)
-       k_EResultNoLauncherSpecified = 117,     // No launcher was specified, but a 
-   // launcher was needed to choose correct realm for operation.
-       k_EResultMustAgreeToSSA = 118,// User must agree to china SSA or global SSA 
-                                 // before login
-       k_EResultLauncherMigrated = 119,        // The specified launcher type is no longer 
-                           // supported; the user should be directed elsewhere
-       k_EResultSteamRealmMismatch = 120,      // The user's realm does not match the 
-                                       // realm of the requested resource
-       k_EResultInvalidSignature = 121,                        // signature check did not match
-       k_EResultParseFailure = 122,            // Failed to parse input
-       k_EResultNoVerifiedPhone = 123, // account does not have a verified phone 
-                                    // number
-} EResult;
-
-typedef struct {
-
-       HSteamUser m_hSteamUser;        // Specific user to whom this callback applies.
-       int m_iCallback; 
-       u8 *m_pubParam;                 // Points to the callback structure
-       int m_cubParam;                 // Size of the data pointed to by m_pubParam
-       
-} CallbackMsg_t;
-
-typedef struct {
-
-       SteamAPICall_t m_hAsyncCall;
-       int m_iCallback;
-       u32 m_cubParam;
-       
-} SteamAPICallCompleted_t;
-
-enum { k_iSteamAPICallCompleted = k_iSteamUtilsCallbacks + 3 };
-
-// Steam universes.  Each universe is a self-contained Steam instance.
-typedef enum {
-       k_EUniverseInvalid = 0,
-       k_EUniversePublic = 1,
-       k_EUniverseBeta = 2,
-       k_EUniverseInternal = 3,
-       k_EUniverseDev = 4,
-       // k_EUniverseRC = 5,                           // no such universe anymore
-       k_EUniverseMax
-} EUniverse_t;
-
-struct SteamIDComponent_t
-{
-#ifdef VALVE_BIG_ENDIAN
-   EUniverse_t                 m_EUniverse : 8
-   unsigned int                m_EAccountType : 4;
-   unsigned int                m_unAccountInstance : 20;
-   u32                                 m_unAccountID : 32;
-#else
-   u32                                 m_unAccountID : 32;
-   unsigned int                m_unAccountInstance : 20;
-   unsigned int                m_EAccountType : 4;
-   EUniverse_t                 m_EUniverse : 8;
-#endif
-};
-
-typedef struct 
-{
-       // 64 bits total
-       union 
-   {
-      struct SteamIDComponent_t m_comp;
-               u64 m_unAll64Bits;
-       };
-} 
-CSteamID;
-
-typedef struct GameID_t
-{
-#ifdef VALVE_BIG_ENDIAN
-       unsigned int m_nModID : 32;
-       unsigned int m_nType : 8;
-       unsigned int m_nAppID : 24;
-#else
-       unsigned int m_nAppID : 24;
-       unsigned int m_nType : 8;
-       unsigned int m_nModID : 32;
-#endif
-} CGameID;
-
-#pragma pack( pop )
-
-/*
- * Standard login
- * =============================================================================
- */
-
-int   SteamAPI_RestartAppIfNecessary( u32 unOwnAppID );
-int   SteamAPI_Init(void);
-void  SteamAPI_Shutdown(void);
-
-/*
- * Server mode login
- * =============================================================================
- */
-
-typedef enum EServerMode EServerMode;
-enum EServerMode
-{
-       eServerModeInvalid = 0,
-       eServerModeNoAuthentication = 1,
-       eServerModeAuthentication = 2,
-       eServerModeAuthenticationAndSecure = 3,
-};
-
-int SteamInternal_GameServer_Init( u32 unIP, u16 usLegacySteamPort, 
-                                   u16 usGamePort, u16 usQueryPort, 
-                                   EServerMode eServerMode, 
-                                   const char *pchVersionString );
-
-/* Initialize SteamGameServer client and interface objects, and set server 
- * properties which may not be changed.
- * After calling this function, you should set any additional server parameters, 
- * and then call ISteamGameServer::LogOnAnonymous() or ISteamGameServer::LogOn()
- *
- * - unIP will usually be zero.  If you are on a machine with multiple IP 
- *   addresses, you can pass a non-zero value here and the relevant sockets will
- *   be bound to that IP.  This can be used to ensure that the IP you desire is 
- *   the one used in the server browser.
- * - usGamePort is the port that clients will connect to for gameplay. You will
- *   usually open up your own socket bound to this port.
- * - usQueryPort is the port that will manage server browser related duties and 
- *   info pings from clients.  If you pass STEAMGAMESERVER_QUERY_PORT_SHARED for
- *   usQueryPort, then it will use "GameSocketShare" mode, which means that the
- *   game is responsible for sending and receiving UDP packets for the master
- *   server updater.  (See ISteamGameServer::HandleIncomingPacket and 
- *   ISteamGameServer::GetNextOutgoingPacket.)
- * - The version string should be in the form x.x.x.x, and is used by the master
- *   server to detect when the server is out of date. (Only servers with the 
- *   latest version will be listed.)
- */
-int   SteamGameServer_Init( u32 unIP, u16 usGamePort, u16 usQueryPort, 
-                            EServerMode eServerMode, 
-                            const char *pchVersionString )
-{
-   return SteamInternal_GameServer_Init( unIP, 0, usGamePort, usQueryPort,
-                                         eServerMode, pchVersionString );
-}
-
-
-void *SteamAPI_SteamGameServer_v014(void);
-void *SteamAPI_SteamGameServer(void) 
-{ 
-   return SteamAPI_SteamGameServer_v014(); 
-}
-
-void SteamAPI_ISteamGameServer_LogOnAnonymous( void* self );
-
-void SteamGameServer_Shutdown(void);
-
-int  SteamGameServer_BSecure(void);
-u64  SteamGameServer_GetSteamID(void);
-
-/*
- * Async callbacks
- * =============================================================================
- */
+#pragma once
+#include "vg_steam_api.h"
 
 typedef struct vg_steam_async_call vg_steam_async_call;
 typedef struct vg_steam_callback_handler vg_steam_callback_handler;
 
-struct vg_steam{
+struct vg_steam
+{
    struct vg_steam_async_call{
       SteamAPICall_t id;
       void *userdata;
-
       void (*p_handler)( void *result, void *userdata );
    }
    calls[4];
@@ -476,166 +21,15 @@ struct vg_steam{
    callback_handlers[32];
    u32 callback_handler_count;
 }
-static vg_steam;
+extern vg_steam;
 
-vg_steam_async_call *vg_alloc_async_steam_api_call(void)
-{
-   if( vg_steam.call_count == vg_list_size(vg_steam.calls) ){
-      vg_fatal_error( "Maximum concurrent API calls exceeded (%u)\n",
-                      vg_steam.call_count );
-   }
-
-   return &vg_steam.calls[ vg_steam.call_count ++ ];
-}
-
-/*
- * Regular callbacks
- * =============================================================================
- */
-
-static void steam_register_callback( u32 id, 
-                                     void (*p_handler)( CallbackMsg_t *msg ) )
-{
-   if( vg_steam.callback_handler_count == 
-       vg_list_size(vg_steam.callback_handlers) )
-   {
-      vg_fatal_error( "Too many steam callback handlers registered (%u)\n", 
-                      vg_steam.callback_handler_count );
-   }
-   
-   vg_steam_callback_handler *handler = 
-      &vg_steam.callback_handlers[ vg_steam.callback_handler_count ++ ];
-
-   handler->p_handler = p_handler;
-   handler->callback_id = id;
-}
-
-/*
- * Event loop
- * =============================================================================
- */
-HSteamPipe SteamAPI_GetHSteamPipe(void);
-HSteamPipe SteamGameServer_GetHSteamPipe(void);
-HSteamUser SteamAPI_GetHSteamUser(void);
-void   SteamAPI_ManualDispatch_Init(void);
-void   SteamAPI_ManualDispatch_RunFrame( HSteamPipe hSteamPipe );
-int    SteamAPI_ManualDispatch_GetNextCallback( HSteamPipe hSteamPipe, 
-                                               CallbackMsg_t *pCallbackMsg );
-void   SteamAPI_ManualDispatch_FreeLastCallback( HSteamPipe hSteamPipe );
-int    SteamAPI_ManualDispatch_GetAPICallResult( HSteamPipe hSteamPipe, 
-         SteamAPICall_t hSteamAPICall, void *pCallback, int cubCallback, 
-         int iCallbackExpected, int *pbFailed );
-
-void   SteamAPI_ReleaseCurrentThreadMemory(void);
-
-static void steamworks_process_api_call( HSteamPipe pipe, 
-                                         CallbackMsg_t *callback )
-{
-   SteamAPICallCompleted_t *pCallCompleted = 
-      (SteamAPICallCompleted_t *)callback->m_pubParam;
-
-   int bFailed;
-   void *call_data = alloca( pCallCompleted->m_cubParam );
-   
-   if( SteamAPI_ManualDispatch_GetAPICallResult( 
-      pipe,
-      pCallCompleted->m_hAsyncCall, 
-      call_data,
-      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<vg_steam.call_count; i++ ){
-         if( vg_steam.calls[i].id != pCallCompleted->m_hAsyncCall ){
-            vg_steam.calls[j ++] = vg_steam.calls[i];
-         }
-         else{
-            vg_steam_async_call *call = &vg_steam.calls[i];
-            call->p_handler( call_data, call->userdata );
-         }
-      }
-
-      if( vg_steam.call_count == j ){
-         vg_error( "No tracker was register for API call\n" );
-      }
-
-      vg_steam.call_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_low( "steamworks_event::callback( %i )\n", callback.m_iCallback );
-       
-               /* Check for dispatching API call results */
-               if( callback.m_iCallback == k_iSteamAPICallCompleted ){
-         steamworks_process_api_call( pipe, &callback );
-               } 
-               else {
-                       /* 
-          * Look at callback.m_iCallback to see what kind of callback it is,
-                        * and dispatch to appropriate handler(s)
-                        * void *data = callback.m_pubParam;
-          */
-
-         for( int i=0; i<vg_steam.callback_handler_count; i++ ){
-            vg_steam_callback_handler *handler = &vg_steam.callback_handlers[i];
-            if( handler->callback_id == callback.m_iCallback ){
-               handler->p_handler( &callback );
-               break;
-            }
-         }
-               }
-               
-               SteamAPI_ManualDispatch_FreeLastCallback( pipe );
-       }
-}
+void steamworks_process_api_call( HSteamPipe pipe, CallbackMsg_t *callback );
+void steamworks_event_loop( HSteamPipe pipe );
+vg_steam_async_call *vg_alloc_async_steam_api_call(void);
+void steam_register_callback( u32 id, void (*p_handler)( CallbackMsg_t *msg ) );
 
 /*
  * 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 */
+void steamworks_ensure_txt( const char *appid_str );