From: hgn Date: Mon, 6 Dec 2021 01:57:05 +0000 (+0000) Subject: dont remember X-Git-Url: https://harrygodden.com/git/?p=fishladder.git;a=commitdiff_plain;h=4e217c7bc7d079364a999ee39773fa70ca25733a dont remember --- diff --git a/fishladder.c b/fishladder.c index 76e09a2..12666a8 100644 --- a/fishladder.c +++ b/fishladder.c @@ -2270,97 +2270,9 @@ static ui_colourset flcol_list_locked = { .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 { @@ -2387,11 +2299,23 @@ void vg_ui(void) } }; + 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; @@ -2410,7 +2334,7 @@ void vg_ui(void) 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(); @@ -2420,7 +2344,172 @@ void vg_ui(void) 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(); } diff --git a/fishladder_resources.h b/fishladder_resources.h index f3b15ca..9a030d1 100644 --- a/fishladder_resources.h +++ b/fishladder_resources.h @@ -690,9 +690,9 @@ struct cmp_level cmp_levels_basic[] = "The competent engineers among you may have already\n" "spotted and utilized these parts of the system\n" "\n" - "We forgot to include the relevant principle tasks\n" - "as part of your training package, you will now be\n" - "tasked to complete them", + "We forgot to include the relevant principle tasks as\n" + "of your training package, you will now be tasked to\n" + "complete them", .serial_id = 15, .linked_unlocks = 1 @@ -701,9 +701,8 @@ struct cmp_level cmp_levels_basic[] = .title = "ROUTING PROBLEM", .map_name = "cmp_routing", .description = - "Things can get a little chaotic on tight boards,\n" - "Do your best to utilize principle 5 to get the job\n" - "done.", + "Things can get a little chaotic on tight boards, do your\n" + "best to utilize principle 5 to get the job done\n", .serial_id = 16, .unlocks = 1 @@ -712,23 +711,22 @@ struct cmp_level cmp_levels_basic[] = .title = "PRINCIPLE 6", .map_name = "cmp_b11", .description = - "While hovering over a simple tile peice, right click\n" - "and drag to start creating a wire. These can be\n" - "connected to the left, or right recieving pins of a\n" - "Twisty Turny(TM) peice.\n" + "While hovering over a simple tile peice, right click and\n" + "drag to start creating a wire. These can be connected to\n" + "the left, or right recieving pins of a Twisty Turny(TM).\n" "\n" "Once connected, the Twisty Turny(TM) will no longer\n" - "'flip flop' as marbles run through them, but instead\n" - "be set to left or right rotating only. As indicated\n" - "by the status arrow beneath them\n" + "'flip flop' as marbles run through them, but instead be\n" + "et to left or right rotating only. As indicated by the\n" + "status arrow beneath them\n" "\n" "When the left or right slot is triggered, the Twisty\n" "Turny(TM) will switch modes according to that input.\n" "\n" - "Trigger wires apply instantaneously, however if both\n" - "the left and right inputs are recieved at the same\n" - "time, this results in no operation being performed,\n" - "and no state changes take place in the Twisty Turny(TM)\n", + "Trigger wires apply instantaneously, however if both the\n" + "left and right inputs are recieved at the same time,\n" + "this results in no operation being performed, and no\n" + "state changes take place in the Twisty Turny(TM)\n", .serial_id = 17, .linked_unlocks = 1 @@ -781,6 +779,7 @@ struct cmp_level cmp_levels_grad[] = .map_name = "cmp_i02", .description = "Split the inputs up into a third of their values\n" + "\n" "Is this possible? -HG", .serial_id = 14 diff --git a/textures/ascii.png b/textures/ascii.png index adf296e..daa341f 100644 Binary files a/textures/ascii.png and b/textures/ascii.png differ diff --git a/vg/vg_steamworks.h b/vg/vg_steamworks.h index 5bc04f2..d4b797b 100644 --- a/vg/vg_steamworks.h +++ b/vg/vg_steamworks.h @@ -1,5 +1,5 @@ #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. @@ -32,7 +32,7 @@ typedef int E_iCallBack_t; 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 }; @@ -98,6 +98,135 @@ 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; + // Structures typedef struct { u32 m_u32; @@ -110,7 +239,7 @@ typedef struct { 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; @@ -122,8 +251,272 @@ typedef struct { 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 ) @@ -141,6 +534,19 @@ void SteamAPI_ReleaseCurrentThreadMemory(); 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(); diff --git a/vg/vg_ui.h b/vg/vg_ui.h index fe46da0..0364739 100644 --- a/vg/vg_ui.h +++ b/vg/vg_ui.h @@ -112,6 +112,7 @@ struct ui_ctx u32 capture_mouse_id; int capture_lock; u32 id_base; + int glyph_base; // User input ui_px mouse[2]; @@ -176,7 +177,7 @@ ui_colourset ui_default_colours = { ui_ctx ui_global_ctx = { .padding = 8, .colours_current = &ui_default_colours, - .colours_main = &ui_default_colours + .colours_main = &ui_default_colours }; @@ -559,14 +560,30 @@ static struct ui_vert *ui_fill_rect( ui_ctx *ctx, ui_rect rect, u32 colour ) return ui_fill_rect_uv( ctx, rect, colour, (ui_px[4]){ 4,124,4,124 } ); } -static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment ) +static void ui_text_use_title( ui_ctx *ctx ) +{ + ctx->glyph_base = 0; +} + +static void ui_text_use_paragraph( ui_ctx *ctx ) +{ + ctx->glyph_base = 6; +} + +enum text_alignment +{ + k_text_alignment_left = 0, + k_text_alignment_center +}; + +static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, enum text_alignment alignment ) { ui_rect text_cursor; text_cursor[0] = ctx->cursor[0]; text_cursor[1] = ctx->cursor[1]; - text_cursor[2] = scale*8; - text_cursor[3] = scale*8; + text_cursor[2] = (scale*8)/2; + text_cursor[3] = (scale*8)/2; u32 current_colour = ctx->override_colour; @@ -576,7 +593,7 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment ) { if( c == '\n' ) { - text_cursor[1] += 10*scale; + text_cursor[1] += (7*scale)/2; text_cursor[0] = ctx->cursor[0]; continue; } @@ -584,9 +601,9 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment ) { u8 glyph_base[2]; u8 glyph_index = c - 32; - glyph_base[0] = glyph_index&0xf; - glyph_base[1] = (glyph_index-glyph_base[0])>>4; - + glyph_base[0] = (glyph_index&0xf); + glyph_base[1] = ctx->glyph_base + ((glyph_index-glyph_base[0])>>4); + glyph_base[0] *= 8; glyph_base[1] *= 8; @@ -636,7 +653,7 @@ static void ui_text( ui_ctx *ctx, const char *str, ui_px scale, int alignment ) continue; } - text_cursor[0] += (ui_glyph_spacing_x*scale)/2; + text_cursor[0] += (ui_glyph_spacing_x*scale)/4; } }