.hover = 0xff655959,
.active = 0xff655959
};
-
-
-
-static void draw_levels_list( struct cmp_level *levels, int count, int unlocked )
-{
- static struct ui_scrollbar sb = {
- .bar_height = 400
- };
-
- ui_px view_height = ui_global_ctx.cursor[3];
- ui_px level_height = 50;
-
- // Level scroll view
- gui_new_node();
- {
- gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
- gui_set_clip( ui_global_ctx.cursor );
-
- ui_global_ctx.cursor[2] = 14;
- gui_align_right();
-
- ui_px content_height = count*level_height;
- if( content_height > view_height )
- {
- ui_scrollbar( &ui_global_ctx, &sb, 1 );
- ui_global_ctx.cursor[1] -= ui_calculate_content_scroll( &sb, content_height );
- }
- else
- {
- gui_fill_rect( ui_global_ctx.cursor, 0xff807373 );
- }
-
- ui_global_ctx.cursor[2] = 240;
- ui_global_ctx.cursor[3] = level_height;
- gui_align_left();
-
- for( int i = 0; i < count; i ++ )
- {
- struct cmp_level *lvl_info = &levels[i];
-
- if( i < unlocked )
- {
- if( lvl_info->completed_score != 0 )
- gui_override_colours( i&0x1? &flcol_list_complete_a: &flcol_list_complete_b );
- else
- gui_override_colours( i&0x1? &flcol_list_a: &flcol_list_b );
- }
- else
- gui_override_colours( &flcol_list_locked );
-
- if( i < unlocked )
- {
- if( gui_button( 2 + i ) == k_button_click )
- {
- console_changelevel( 1, &lvl_info->map_name );
- }
-
- ui_global_ctx.override_colour = 0xffffffff;
- gui_text( lvl_info->title, 3, 0 );
- ui_global_ctx.cursor[1] += 18;
- gui_text( "incomplete", 2, 0 );
- }
- else
- {
- gui_button( 2 + i );
-
- ui_global_ctx.override_colour = 0xff786f6f;
- gui_text( "???", 3, 0 );
- ui_global_ctx.cursor[1] += 18;
- gui_text( "locked", 2, 0 );
- }
-
- gui_end_down();
- }
-
- gui_reset_colours();
- gui_release_clip();
- }
- gui_end_down();
-}
-
void vg_ui(void)
{
- ui_global_ctx.cursor[0] = 0;
- ui_global_ctx.cursor[1] = 0;
- ui_global_ctx.cursor[2] = 256;
-
- gui_fill_y();
-
- ui_global_ctx.id_base = 4 << 16;
-
+ // UI memory
static int pack_selection = 0;
static struct pack_info
{
}
};
+ static struct cmp_level *level_selected = NULL;
+
+ // UI Code
+ ui_global_ctx.cursor[0] = 0;
+ ui_global_ctx.cursor[1] = 0;
+ ui_global_ctx.cursor[2] = 256;
+
+ gui_fill_y();
+
+ ui_global_ctx.id_base = 4 << 16;
+
gui_new_node();
{
+ gui_capture_mouse( 9999 );
gui_fill_rect( ui_global_ctx.cursor, 0xff5577ff );
- gui_text( "ASSIGNMENTS", 4, 0 );
+ gui_text( "ASSIGNMENTS", 8, 0 );
ui_global_ctx.cursor[1] += 30;
ui_global_ctx.cursor[3] = 25;
pack_selection = i;
ui_global_ctx.cursor[1] += 2;
- gui_text( pack_infos[i].name, 2, 0 );
+ gui_text( pack_infos[i].name, 4, 0 );
gui_end_right();
gui_reset_colours();
ui_global_ctx.cursor[3] = 500;
- draw_levels_list( pack_infos[ pack_selection ].levels, pack_infos[ pack_selection ].level_count, 3 );
+ // DRAW LEVEL SELECTION LIST
+ {
+ struct cmp_level *levels = pack_infos[ pack_selection ].levels;
+ int count = pack_infos[ pack_selection ].level_count;
+ int unlocked = 3000;
+
+ static struct ui_scrollbar sb = {
+ .bar_height = 400
+ };
+
+ ui_px view_height = ui_global_ctx.cursor[3];
+ ui_px level_height = 50;
+
+ // Level scroll view
+ gui_new_node();
+ {
+ gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
+ gui_set_clip( ui_global_ctx.cursor );
+
+ ui_global_ctx.cursor[2] = 14;
+ gui_align_right();
+
+ ui_px content_height = count*level_height;
+ if( content_height > view_height )
+ {
+ ui_scrollbar( &ui_global_ctx, &sb, 1 );
+ ui_global_ctx.cursor[1] -= ui_calculate_content_scroll( &sb, content_height );
+ }
+ else
+ {
+ gui_fill_rect( ui_global_ctx.cursor, 0xff807373 );
+ }
+
+ ui_global_ctx.cursor[2] = 240;
+ ui_global_ctx.cursor[3] = level_height;
+ gui_align_left();
+
+ for( int i = 0; i < count; i ++ )
+ {
+ struct cmp_level *lvl_info = &levels[i];
+
+ if( i < unlocked )
+ {
+ if( lvl_info->completed_score != 0 )
+ gui_override_colours( i&0x1? &flcol_list_complete_a: &flcol_list_complete_b );
+ else
+ gui_override_colours( i&0x1? &flcol_list_a: &flcol_list_b );
+ }
+ else
+ gui_override_colours( &flcol_list_locked );
+
+ if( i < unlocked )
+ {
+ if( gui_button( 2 + i ) == k_button_click )
+ level_selected = &levels[i];
+
+ ui_global_ctx.override_colour = 0xffffffff;
+ gui_text( lvl_info->title, 6, 0 );
+ ui_global_ctx.cursor[1] += 18;
+ gui_text( "incomplete", 4, 0 );
+ }
+ else
+ {
+ gui_button( 2 + i );
+
+ ui_global_ctx.override_colour = 0xff786f6f;
+ gui_text( "???", 6, 0 );
+ ui_global_ctx.cursor[1] += 18;
+ gui_text( "locked", 4, 0 );
+ }
+
+ gui_end_down();
+ }
+
+ gui_reset_colours();
+ gui_release_clip();
+ }
+ gui_end_down();
+ }
+ }
+ gui_end_right();
+
+ // Selected level UI
+ // ============================================================
+
+ if( level_selected )
+ {
+ ui_global_ctx.cursor[0] += 16;
+ ui_global_ctx.cursor[1] += 16;
+ ui_global_ctx.cursor[2] = 512-40;
+ ui_global_ctx.cursor[3] = 560-16;
+
+ gui_new_node();
+ {
+ gui_capture_mouse( 9999 );
+
+ gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
+ ui_global_ctx.cursor[1] += 4;
+ gui_text( level_selected->title, 6, 0 );
+
+ ui_global_ctx.cursor[1] += 30;
+ ui_rect_pad( ui_global_ctx.cursor, 8 );
+ ui_global_ctx.cursor[3] = 300;
+
+ gui_new_node();
+ {
+ gui_fill_rect( ui_global_ctx.cursor, 0xff655959 );
+ }
+ gui_end_down();
+
+ ui_text_use_paragraph( &ui_global_ctx );
+ ui_global_ctx.cursor[1] += 2;
+
+ gui_text( level_selected->description, 5, 0 );
+ ui_text_use_title( &ui_global_ctx );
+
+ // Buttons at the bottom
+ ui_global_ctx.cursor[3] = 30;
+ ui_global_ctx.cursor[2] = 80;
+
+ gui_align_bottom();
+ ui_global_ctx.cursor[1] -= 8;
+
+ if( gui_button( 3000 ) == k_button_click )
+ {
+ level_selected = NULL;
+ }
+ gui_text( "Back", 6, 0 );
+ gui_end();
+
+ gui_align_right();
+ ui_global_ctx.cursor[2] = 170;
+ ui_global_ctx.cursor[0] -= 8 + 170 + 2;
+
+ {
+ gui_override_colours( &flcol_list_locked );
+ if( gui_button( 3001 ) == k_button_click )
+ vg_error( "UNIMPLEMENTED\n" );
+
+ gui_text( "Restore Solution", 6, 0 );
+ gui_end_right();
+ }
+
+ ui_global_ctx.cursor[0] += 2;
+ ui_global_ctx.cursor[2] = 80;
+
+ {
+ gui_override_colours( &flcol_list_complete_a );
+ if( gui_button( 3002 ) == k_button_click )
+ console_changelevel( 1, &level_selected->map_name );
+ gui_text( "Play", 6, 0 );
+ gui_end();
+ }
+
+ gui_reset_colours();
+ }
+ gui_end_right();
+
+ ui_global_ctx.cursor[0] += 16;
+ ui_global_ctx.cursor[3] = 250;
+
+ // If has results
+ gui_new_node();
+ {
+ gui_fill_rect( ui_global_ctx.cursor, 0xff5a4e4d );
+ }
+ gui_end();
}
- gui_end();
}
#if defined(__linux__) || defined(__APPLE__)
-// The 32-bit version of gcc has the alignment requirement for uint64 and double set to
+// 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.
typedef u32 SNetSocket_t; // CreateP2PConnectionSocket()
typedef u32 SNetListenSocket_t; // CreateListenSocket()
-typedef u64 uint64_steamid;
+typedef u64 u64_steamid;
typedef u64 SteamAPICall_t;
enum { k_iSteamUserCallbacks = 100 };
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;
+
// Structures
typedef struct {
u32 m_u32;
HSteamUser m_hSteamUser; // Specific user to whom this callback applies.
int m_iCallback; // Callback identifier. (Corresponds to the k_iCallback enum in the callback structure.)
- uint8_t *m_pubParam; // Points to the callback structure
+ u8 *m_pubParam; // Points to the callback structure
int m_cubParam; // Size of the data pointed to by m_pubParam
} CallbackMsg_t;
u32 m_cubParam;
} SteamAPICallCompleted_t;
+
+// 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;
+
+typedef struct
+{
+ // 64 bits total
+ union {
+ struct SteamIDComponent_t
+ {
+#ifdef VALVE_BIG_ENDIAN
+ EUniverse_t m_EUniverse : 8; // universe this account belongs to
+ unsigned int m_EAccountType : 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
+ unsigned int m_unAccountInstance : 20; // dynamic instance ID
+ u32 m_unAccountID : 32; // unique account identifier
+#else
+ u32 m_unAccountID : 32; // unique account identifier
+ unsigned int m_unAccountInstance : 20; // dynamic instance ID
+ unsigned int m_EAccountType : 4; // type of account - can't show as EAccountType, due to signed / unsigned difference
+ EUniverse_t m_EUniverse : 8; // universe this account belongs to
+#endif
+ } 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;
+
#define SW_CBID_SteamAPICallCompleted (k_iSteamUtilsCallbacks + 3)
+typedef u64 UGCHandle_t;
+typedef u64 PublishedFileUpdateHandle_t;
+typedef u64 PublishedFileId_t;
+const PublishedFileId_t k_PublishedFileIdInvalid = 0;
+const UGCHandle_t k_UGCHandleInvalid = 0xffffffffffffffffull;
+const PublishedFileUpdateHandle_t k_PublishedFileUpdateHandleInvalid = 0xffffffffffffffffull;
+
+// Handle for writing to Steam Cloud
+typedef u64 UGCFileWriteStreamHandle_t;
+
+// size limit on stat or achievement name (UTF-8 encoded)
+enum { k_cchStatNameMax = 128 };
+
+// maximum number of bytes for a leaderboard name (UTF-8 encoded)
+enum { k_cchLeaderboardNameMax = 128 };
+
+// maximum number of details i32's storable for a single leaderboard entry
+enum { k_cLeaderboardDetailsMax = 64 };
+
+// handle to a single leaderboard
+typedef u64 SteamLeaderboard_t;
+
+// handle to a set of downloaded entries in a leaderboard
+typedef u64 SteamLeaderboardEntries_t;
+
+// type of data request, when downloading leaderboard entries
+typedef enum ELeaderboardDataRequest
+{
+ k_ELeaderboardDataRequestGlobal = 0,
+ k_ELeaderboardDataRequestGlobalAroundUser = 1,
+ k_ELeaderboardDataRequestFriends = 2,
+ k_ELeaderboardDataRequestUsers = 3
+} ELeaderboardDataRequest;
+
+// the sort order of a leaderboard
+typedef enum ELeaderboardSortMethod
+{
+ k_ELeaderboardSortMethodNone = 0,
+ k_ELeaderboardSortMethodAscending = 1, // top-score is lowest number
+ k_ELeaderboardSortMethodDescending = 2, // top-score is highest number
+} ELeaderboardSortMethod;
+
+// the display type (used by the Steam Community web site) for a leaderboard
+typedef enum ELeaderboardDisplayType
+{
+ k_ELeaderboardDisplayTypeNone = 0,
+ k_ELeaderboardDisplayTypeNumeric = 1, // simple numerical score
+ k_ELeaderboardDisplayTypeTimeSeconds = 2, // the score represents a time, in seconds
+ k_ELeaderboardDisplayTypeTimeMilliSeconds = 3, // the score represents a time, in milliseconds
+} ELeaderboardDisplayType;
+
+typedef enum ELeaderboardUploadScoreMethod
+{
+ k_ELeaderboardUploadScoreMethodNone = 0,
+ k_ELeaderboardUploadScoreMethodKeepBest = 1, // Leaderboard will keep user's best score
+ k_ELeaderboardUploadScoreMethodForceUpdate = 2, // Leaderboard will always replace score with specified
+} ELeaderboardUploadScoreMethod;
+
+// a single entry in a leaderboard, as returned by GetDownloadedLeaderboardEntry()
+typedef struct LeaderboardEntry_t
+{
+ CSteamID m_steamIDUser; // user with the entry - use SteamFriends()->GetFriendPersonaName() & SteamFriends()->GetFriendAvatar() to get more info
+ i32 m_nGlobalRank; // [1..N], where N is the number of users with an entry in the leaderboard
+ i32 m_nScore; // score as set in the leaderboard
+ i32 m_cDetails; // number of i32 details available for this entry
+ UGCHandle_t m_hUGC; // handle for UGC attached to the entry
+} LeaderboardEntry_t;
+
+//-----------------------------------------------------------------------------
+// Purpose: called when the latests stats and achievements have been received
+// from the server
+//-----------------------------------------------------------------------------
+typedef struct UserStatsReceived_t
+{
+ u64 m_nGameID; // Game these stats are for
+ EResult m_eResult; // Success / error fetching the stats
+ CSteamID m_steamIDUser; // The user for whom the stats are retrieved for
+} UserStatsReceived_t;
+#define SW_CBID_UserStatsReceived (k_iSteamUserStatsCallbacks + 1)
+
+//-----------------------------------------------------------------------------
+// Purpose: result of a request to store the user stats for a game
+//-----------------------------------------------------------------------------
+typedef struct UserStatsStored_t
+{
+ u64 m_nGameID; // Game these stats are for
+ EResult m_eResult; // success / error
+} UserStatsStored_t;
+#define SW_CBID_UserStatsStored (k_iSteamUserStatsCallbacks + 2)
+
+//-----------------------------------------------------------------------------
+// Purpose: result of a request to store the achievements for a game, or an
+// "indicate progress" call. If both m_nCurProgress and m_nMaxProgress
+// are zero, that means the achievement has been fully unlocked.
+//-----------------------------------------------------------------------------
+typedef struct UserAchievementStored_t
+{
+ u64 m_nGameID; // Game this is for
+ int m_bGroupAchievement; // if this is a "group" achievement
+ char m_rgchAchievementName[k_cchStatNameMax]; // name of the achievement
+ u32 m_nCurProgress; // current progress towards the achievement
+ u32 m_nMaxProgress; // "out of" this many
+} UserAchievementStored_t;
+#define SW_CBID_UserAchievementStored (k_iSteamUserStatsCallbacks + 3)
+
+//-----------------------------------------------------------------------------
+// Purpose: call result for finding a leaderboard, returned as a result of FindOrCreateLeaderboard() or FindLeaderboard()
+// use CCallResult<> to map this async result to a member function
+//-----------------------------------------------------------------------------
+typedef struct LeaderboardFindResult_t
+{
+ SteamLeaderboard_t m_hSteamLeaderboard; // handle to the leaderboard serarched for, 0 if no leaderboard found
+ u8 m_bLeaderboardFound; // 0 if no leaderboard found
+} LeaderboardFindResult_t;
+#define SW_CBID_LeaderboardFindResult (k_iSteamUserStatsCallbacks + 4)
+
+//-----------------------------------------------------------------------------
+// Purpose: call result indicating scores for a leaderboard have been downloaded and are ready to be retrieved, returned as a result of DownloadLeaderboardEntries()
+// use CCallResult<> to map this async result to a member function
+//-----------------------------------------------------------------------------
+typedef struct LeaderboardScoresDownloaded_t
+{
+ SteamLeaderboard_t m_hSteamLeaderboard;
+ SteamLeaderboardEntries_t m_hSteamLeaderboardEntries; // the handle to pass into GetDownloadedLeaderboardEntries()
+ int m_cEntryCount; // the number of entries downloaded
+} LeaderboardScoresDownloaded_t;
+#define SW_CBID_LeaderboardScoresDownloaded (k_iSteamUserStatsCallbacks + 5)
+
+//-----------------------------------------------------------------------------
+// Purpose: call result indicating scores has been uploaded, returned as a result of UploadLeaderboardScore()
+// use CCallResult<> to map this async result to a member function
+//-----------------------------------------------------------------------------
+typedef struct LeaderboardScoreUploaded_t
+{
+ u8 m_bSuccess; // 1 if the call was successful
+ SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was
+ i32 m_nScore; // the score that was attempted to set
+ u8 m_bScoreChanged; // true if the score in the leaderboard change, false if the existing score was better
+ int m_nGlobalRankNew; // the new global rank of the user in this leaderboard
+ int m_nGlobalRankPrevious; // the previous global rank of the user in this leaderboard; 0 if the user had no existing entry in the leaderboard
+} LeaderboardScoreUploaded_t;
+#define SW_CBID_LeaderboardScoreUploaded (k_iSteamUserStatsCallbacks + 6)
+
+typedef struct NumberOfCurrentPlayers_t
+{
+ u8 m_bSuccess; // 1 if the call was successful
+ i32 m_cPlayers; // Number of players currently playing
+} NumberOfCurrentPlayers_t;
+#define SW_CBID_NumberOfCurrentPlayers (k_iSteamUserStatsCallbacks + 7)
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Callback indicating that a user's stats have been unloaded.
+// Call RequestUserStats again to access stats for this user
+//-----------------------------------------------------------------------------
+typedef struct UserStatsUnloaded_t
+{
+ CSteamID m_steamIDUser; // User whose stats have been unloaded
+} UserStatsUnloaded_t;
+#define SW_CBID_UserStatsUnloaded (k_iSteamUserStatsCallbacks + 8)
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Callback indicating that an achievement icon has been fetched
+//-----------------------------------------------------------------------------
+typedef struct UserAchievementIconFetched_t
+{
+ CGameID m_nGameID; // Game this is for
+ char m_rgchAchievementName[k_cchStatNameMax]; // name of the achievement
+ int m_bAchieved; // Is the icon for the achieved or not achieved version?
+ int m_nIconHandle; // Handle to the image, which can be used in SteamUtils()->GetImageRGBA(), 0 means no image is set for the achievement
+} UserAchievementIconFetched_t;
+#define SW_CBID_UserAchievementIconFetched (k_iSteamUserStatsCallbacks + 9)
+
+//-----------------------------------------------------------------------------
+// Purpose: Callback indicating that global achievement percentages are fetched
+//-----------------------------------------------------------------------------
+typedef struct GlobalAchievementPercentagesReady_t
+{
+ u64 m_nGameID; // Game this is for
+ EResult m_eResult; // Result of the operation
+} GlobalAchievementPercentagesReady_t;
+#define SW_CBID_GlobalAchievementPercentagesReady (k_iSteamUserStatsCallbacks + 10)
+
+//-----------------------------------------------------------------------------
+// Purpose: call result indicating UGC has been uploaded, returned as a result of SetLeaderboardUGC()
+//-----------------------------------------------------------------------------
+typedef struct LeaderboardUGCSet_t
+{
+ EResult m_eResult; // The result of the operation
+ SteamLeaderboard_t m_hSteamLeaderboard; // the leaderboard handle that was
+} LeaderboardUGCSet_t;
+#define SW_CBID_LeaderboardUGCSet (k_iSteamUserStatsCallbacks + 11)
+
+//-----------------------------------------------------------------------------
+// Purpose: callback indicating that PS3 trophies have been installed
+//-----------------------------------------------------------------------------
+typedef struct PS3TrophiesInstalled_t
+{
+ u64 m_nGameID; // Game these stats are for
+ EResult m_eResult; // The result of the operation
+ u64 m_ulRequiredDiskSpace; // If m_eResult is k_EResultDiskFull, will contain the amount of space needed to install trophies
+
+} PS3TrophiesInstalled_t;
+#define SW_CBID_TrophiesInstalled (k_iSteamUserStatsCallbacks + 12)
+
+//-----------------------------------------------------------------------------
+// Purpose: callback indicating global stats have been received.
+// Returned as a result of RequestGlobalStats()
+//-----------------------------------------------------------------------------
+typedef struct GlobalStatsReceived_t
+{
+ u64 m_nGameID; // Game global stats were requested for
+ EResult m_eResult; // The result of the request
+} GlobalStatsReceived_t;
+#define SW_CBID_GlobalStatsReceived (k_iSteamUserStatsCallbacks + 12)
#pragma pack( pop )
int SteamAPI_ISteamUserStats_SetAchievement( ISteamUserStats *self, const char *pchName );
+// Leaderboards
+SteamAPICall_t SteamAPI_ISteamUserStats_FindOrCreateLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName, ELeaderboardSortMethod eLeaderboardSortMethod, ELeaderboardDisplayType eLeaderboardDisplayType );
+SteamAPICall_t SteamAPI_ISteamUserStats_FindLeaderboard( ISteamUserStats* self, const char * pchLeaderboardName );
+const char * SteamAPI_ISteamUserStats_GetLeaderboardName( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard );
+int SteamAPI_ISteamUserStats_GetLeaderboardEntryCount( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard );
+ELeaderboardSortMethod SteamAPI_ISteamUserStats_GetLeaderboardSortMethod( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard );
+ELeaderboardDisplayType SteamAPI_ISteamUserStats_GetLeaderboardDisplayType( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard );
+SteamAPICall_t SteamAPI_ISteamUserStats_DownloadLeaderboardEntries( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardDataRequest eLeaderboardDataRequest, int nRangeStart, int nRangeEnd );
+SteamAPICall_t SteamAPI_ISteamUserStats_DownloadLeaderboardEntriesForUsers( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, CSteamID * prgUsers, int cUsers );
+int SteamAPI_ISteamUserStats_GetDownloadedLeaderboardEntry( ISteamUserStats* self, SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, LeaderboardEntry_t * pLeaderboardEntry, i32 * pDetails, int cDetailsMax );
+SteamAPICall_t SteamAPI_ISteamUserStats_UploadLeaderboardScore( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, ELeaderboardUploadScoreMethod eLeaderboardUploadScoreMethod, i32 nScore, const i32 * pScoreDetails, int cScoreDetailsCount );
+SteamAPICall_t SteamAPI_ISteamUserStats_AttachLeaderboardUGC( ISteamUserStats* self, SteamLeaderboard_t hSteamLeaderboard, UGCHandle_t hUGC );
+
HSteamPipe SteamAPI_GetHSteamPipe();
HSteamUser SteamAPI_GetHSteamUser();