diff options
Diffstat (limited to 'Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp')
| -rw-r--r-- | Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp | 1202 |
1 files changed, 1202 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp b/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp new file mode 100644 index 00000000..428b3e88 --- /dev/null +++ b/Minecraft.Client/Common/XUI/XUI_Leaderboards.cpp @@ -0,0 +1,1202 @@ +#include "stdafx.h" +#include <xuiresource.h> +#include <xuiapp.h> +#include "XUI_Leaderboards.h" +#include "..\..\..\Minecraft.World\Tile.h" +#include "..\..\..\Minecraft.World\Item.h" +#include "XUI_Ctrl_CraftIngredientSlot.h" +#include "XUI_XZP_Icons.h" + +LPCWSTR CScene_Leaderboards::m_TitleIconNameA[7]= +{ + L"XuiHSlot1", + L"XuiHSlot2", + L"XuiHSlot3", + L"XuiHSlot4", + L"XuiHSlot5", + L"XuiHSlot6", + L"XuiHSlot7", +}; + +LPCWSTR CScene_Leaderboards::m_TextColumnNameA[7]= +{ + L"text_Column1", + L"text_Column2", + L"text_Column3", + L"text_Column4", + L"text_Column5", + L"text_Column6", + L"text_Column7", +}; + + +// if the value is greater than 511, it's an xzp icon that needs displayed, rather than the game icon +const int CScene_Leaderboards::TitleIcons[CScene_Leaderboards::NUM_LEADERBOARDS][7] = +{ + { XZP_ICON_WALKED, XZP_ICON_FALLEN, Item::minecart_Id, Item::boat_Id, NULL }, + { Tile::dirt_Id, Tile::stoneBrick_Id, Tile::sand_Id, Tile::rock_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id }, + { Item::egg_Id, Item::wheat_Id, Tile::mushroom1_Id, Tile::reeds_Id, Item::milk_Id, Tile::pumpkin_Id, NULL }, + { XZP_ICON_ZOMBIE, XZP_ICON_SKELETON, XZP_ICON_CREEPER, XZP_ICON_SPIDER, XZP_ICON_SPIDERJOCKEY, XZP_ICON_ZOMBIEPIGMAN, XZP_ICON_SLIME }, +}; + +const int CScene_Leaderboards::LEADERBOARD_HEADERS[CScene_Leaderboards::NUM_LEADERBOARDS][4] = { + { SPASTRING_LB_TRAVELLING_PEACEFUL_NAME, SPASTRING_LB_TRAVELLING_EASY_NAME, SPASTRING_LB_TRAVELLING_NORMAL_NAME, SPASTRING_LB_TRAVELLING_HARD_NAME }, + { SPASTRING_LB_MINING_BLOCKS_PEACEFUL_NAME, SPASTRING_LB_MINING_BLOCKS_EASY_NAME, SPASTRING_LB_MINING_BLOCKS_NORMAL_NAME, SPASTRING_LB_MINING_BLOCKS_HARD_NAME }, + { SPASTRING_LB_FARMING_PEACEFUL_NAME, SPASTRING_LB_FARMING_EASY_NAME, SPASTRING_LB_FARMING_NORMAL_NAME, SPASTRING_LB_FARMING_HARD_NAME }, + { NULL, SPASTRING_LB_KILLS_EASY_NAME, SPASTRING_LB_KILLS_NORMAL_NAME, SPASTRING_LB_KILLS_HARD_NAME }, +}; + +const CScene_Leaderboards::LeaderboardDescriptor CScene_Leaderboards::LEADERBOARD_DESCRIPTORS[CScene_Leaderboards::NUM_LEADERBOARDS][4] = { + { + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_PEACEFUL, 4, STATS_COLUMN_TRAVELLING_PEACEFUL_WALKED, STATS_COLUMN_TRAVELLING_PEACEFUL_FALLEN, STATS_COLUMN_TRAVELLING_PEACEFUL_MINECART, STATS_COLUMN_TRAVELLING_PEACEFUL_BOAT, NULL, NULL, NULL,NULL), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_EASY, 4, STATS_COLUMN_TRAVELLING_EASY_WALKED, STATS_COLUMN_TRAVELLING_EASY_FALLEN, STATS_COLUMN_TRAVELLING_EASY_MINECART, STATS_COLUMN_TRAVELLING_EASY_BOAT, NULL, NULL, NULL,NULL), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_NORMAL, 4, STATS_COLUMN_TRAVELLING_NORMAL_WALKED, STATS_COLUMN_TRAVELLING_NORMAL_FALLEN, STATS_COLUMN_TRAVELLING_NORMAL_MINECART, STATS_COLUMN_TRAVELLING_NORMAL_BOAT, NULL, NULL, NULL,NULL), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_TRAVELLING_HARD, 4, STATS_COLUMN_TRAVELLING_HARD_WALKED, STATS_COLUMN_TRAVELLING_HARD_FALLEN, STATS_COLUMN_TRAVELLING_HARD_MINECART, STATS_COLUMN_TRAVELLING_HARD_BOAT, NULL, NULL, NULL,NULL), + }, + { + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_PEACEFUL, 7, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_DIRT, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_STONE, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_SAND, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_GRAVEL, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_CLAY, STATS_COLUMN_MINING_BLOCKS_PEACEFUL_OBSIDIAN,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_EASY, 7, STATS_COLUMN_MINING_BLOCKS_EASY_DIRT, STATS_COLUMN_MINING_BLOCKS_EASY_STONE, STATS_COLUMN_MINING_BLOCKS_EASY_SAND, STATS_COLUMN_MINING_BLOCKS_EASY_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_EASY_GRAVEL, STATS_COLUMN_MINING_BLOCKS_EASY_CLAY, STATS_COLUMN_MINING_BLOCKS_EASY_OBSIDIAN,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_NORMAL, 7, STATS_COLUMN_MINING_BLOCKS_NORMAL_DIRT, STATS_COLUMN_MINING_BLOCKS_NORMAL_STONE, STATS_COLUMN_MINING_BLOCKS_NORMAL_SAND, STATS_COLUMN_MINING_BLOCKS_NORMAL_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_NORMAL_GRAVEL, STATS_COLUMN_MINING_BLOCKS_NORMAL_CLAY, STATS_COLUMN_MINING_BLOCKS_NORMAL_OBSIDIAN,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_MINING_BLOCKS_HARD, 7, STATS_COLUMN_MINING_BLOCKS_HARD_DIRT, STATS_COLUMN_MINING_BLOCKS_HARD_STONE, STATS_COLUMN_MINING_BLOCKS_HARD_SAND, STATS_COLUMN_MINING_BLOCKS_HARD_COBBLESTONE, STATS_COLUMN_MINING_BLOCKS_HARD_GRAVEL, STATS_COLUMN_MINING_BLOCKS_HARD_CLAY, STATS_COLUMN_MINING_BLOCKS_HARD_OBSIDIAN,NULL ), + }, + { + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_FARMING_PEACEFUL, 6, STATS_COLUMN_FARMING_PEACEFUL_EGGS, STATS_COLUMN_FARMING_PEACEFUL_WHEAT, STATS_COLUMN_FARMING_PEACEFUL_MUSHROOMS, STATS_COLUMN_FARMING_PEACEFUL_SUGARCANE, STATS_COLUMN_FARMING_PEACEFUL_MILK, STATS_COLUMN_FARMING_PEACEFUL_PUMPKINS, NULL,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_FARMING_EASY, 6, STATS_COLUMN_FARMING_EASY_EGGS, STATS_COLUMN_FARMING_PEACEFUL_WHEAT, STATS_COLUMN_FARMING_EASY_MUSHROOMS, STATS_COLUMN_FARMING_EASY_SUGARCANE, STATS_COLUMN_FARMING_EASY_MILK, STATS_COLUMN_FARMING_EASY_PUMPKINS, NULL,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_FARMING_NORMAL, 6, STATS_COLUMN_FARMING_NORMAL_EGGS, STATS_COLUMN_FARMING_NORMAL_WHEAT, STATS_COLUMN_FARMING_NORMAL_MUSHROOMS, STATS_COLUMN_FARMING_NORMAL_SUGARCANE, STATS_COLUMN_FARMING_NORMAL_MILK, STATS_COLUMN_FARMING_NORMAL_PUMPKINS, NULL,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_FARMING_HARD, 6, STATS_COLUMN_FARMING_HARD_EGGS, STATS_COLUMN_FARMING_HARD_WHEAT, STATS_COLUMN_FARMING_HARD_MUSHROOMS, STATS_COLUMN_FARMING_HARD_SUGARCANE, STATS_COLUMN_FARMING_HARD_MILK, STATS_COLUMN_FARMING_HARD_PUMPKINS, NULL,NULL ), + }, + { + CScene_Leaderboards::LeaderboardDescriptor( NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_KILLS_EASY, 7, STATS_COLUMN_KILLS_EASY_ZOMBIES, STATS_COLUMN_KILLS_EASY_SKELETONS, STATS_COLUMN_KILLS_EASY_CREEPERS, STATS_COLUMN_KILLS_EASY_SPIDERS, STATS_COLUMN_KILLS_EASY_SPIDERJOCKEYS, STATS_COLUMN_KILLS_EASY_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_EASY_SLIME,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_KILLS_NORMAL, 7, STATS_COLUMN_KILLS_NORMAL_ZOMBIES, STATS_COLUMN_KILLS_NORMAL_SKELETONS, STATS_COLUMN_KILLS_NORMAL_CREEPERS, STATS_COLUMN_KILLS_NORMAL_SPIDERS, STATS_COLUMN_KILLS_NORMAL_SPIDERJOCKEYS, STATS_COLUMN_KILLS_NORMAL_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_NORMAL_SLIME,NULL ), + CScene_Leaderboards::LeaderboardDescriptor( STATS_VIEW_KILLS_HARD, 7, STATS_COLUMN_KILLS_HARD_ZOMBIES, STATS_COLUMN_KILLS_HARD_SKELETONS, STATS_COLUMN_KILLS_HARD_CREEPERS, STATS_COLUMN_KILLS_HARD_SPIDERS, STATS_COLUMN_KILLS_HARD_SPIDERJOCKEYS, STATS_COLUMN_KILLS_HARD_ZOMBIEPIGMEN, STATS_COLUMN_KILLS_HARD_SLIME,NULL ), + }, +}; + +HRESULT CScene_Leaderboards::OnInit(XUIMessageInit *pInitData, BOOL &bHandled) +{ + m_iPad = *(int *)pInitData->pvInitData; + MapChildControls(); + m_bReady=false; + + // if we're not in the game, we need to use basescene 0 + if(Minecraft::GetInstance()->level==NULL) + { + m_iPad=DEFAULT_XUI_MENU_USER; + } + + m_bPopulatedOnce = false; + + ui.SetTooltips(m_iPad,-1, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, -1); + CXuiSceneBase::ShowLogo( m_iPad, FALSE ); + + m_friends = NULL; + m_numFriends = 0; + m_filteredFriends = NULL; + m_numFilteredFriends = 0; + + m_newTop = m_newSel = -1; + + m_isProcessingStatsRead = false; + + // Alert the app the we want to be informed of ethernet connections + app.SetLiveLinkRequired( true ); + + LeaderboardManager::Instance()->OpenSession(); + + //GetFriends(); + + m_currentLeaderboard = 0; + m_currentDifficulty = 2; + SetLeaderboardHeader(); + + m_currentFilter = LeaderboardManager::eFM_Friends; + wchar_t filterBuffer[40]; + swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS)); + m_textFilter.SetText(filterBuffer); + + wchar_t entriesBuffer[40]; + swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), 0); + m_textEntries.SetText(entriesBuffer); + + ReadStats(-1); + + // title icons + for(int i=0;i<7;i++) + { + m_pHTitleIconSlots[i]=NULL; + m_fTitleIconXPositions[i]=0.0f; + m_fTextXPositions[i]=0.0f; + m_hTextEntryA[i]=NULL; + } + + + bHandled = TRUE; + return S_OK; +} + + +void CScene_Leaderboards::Reposition(int iNumber) +{ + float fIconSize; // including gap + float fNewIconIncrement; + D3DXVECTOR3 vPos; + + fIconSize=(m_fTitleIconXPositions[6]-m_fTitleIconXPositions[0])/6.0f; + fNewIconIncrement=(fIconSize*7.0f)/(float)iNumber; + + // reposition the title icons based on the number there are + for(int i=0;i<iNumber;i++) + { + m_pHTitleIconSlots[i]->GetPosition(&vPos); + vPos.x=m_fTitleIconXPositions[0]+(((float)i)*fNewIconIncrement)+(fNewIconIncrement-fIconSize)/2.0f; + m_pHTitleIconSlots[i]->SetPosition(&vPos); + } +} + +void CScene_Leaderboards::RepositionText(int iNumber) +{ + float fTextSize; // including gap + float fNewTextIncrement; + D3DXVECTOR3 vPos; + + fTextSize=(m_fTextXPositions[6]-m_fTextXPositions[0])/6.0f; + fNewTextIncrement=(fTextSize*7.0f)/(float)iNumber; + + // reposition the title icons based on the number there are + for(int i=0;i<iNumber;i++) + { + // and reposition the text + XuiElementGetPosition(m_hTextEntryA[i],&vPos); + vPos.x=m_fTextXPositions[0]+(((float)i)*fNewTextIncrement); + XuiElementSetPosition(m_hTextEntryA[i],&vPos); + // and change the size + float fWidth,fHeight; + XuiElementGetBounds(m_hTextEntryA[i],&fWidth,&fHeight); + XuiElementSetBounds(m_hTextEntryA[i],fNewTextIncrement,fHeight); + } +} + +HRESULT CScene_Leaderboards::OnDestroy() +{ + LeaderboardManager::Instance()->CancelOperation(); + LeaderboardManager::Instance()->CloseSession(); + + // Alert the app the we no longer want to be informed of ethernet connections + app.SetLiveLinkRequired( false ); + + while( m_isProcessingStatsRead ) + { + Sleep( 10 ); + } + + if( m_friends != NULL ) + delete [] m_friends; + + if( m_filteredFriends != NULL ) + delete [] m_filteredFriends; + + return S_OK; +} + +HRESULT CScene_Leaderboards::OnNotifySetFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled) +{ + UpdateTooltips(); + return S_OK; +} + +HRESULT CScene_Leaderboards::OnNotifySelChanged(HXUIOBJ hObjSource, XUINotifySelChanged *pNotifySelChangedData, BOOL& bHandled) +{ + + if(m_bReady && pNotifySelChangedData->iOldItem!=-1) + { + CXuiSceneBase::PlayUISFX(eSFX_Focus); + } + + return S_OK; +} + +void CScene_Leaderboards::UpdateTooltips() +{ + int iTooltipFriendRequest=-1; + int iTooltipGamerCardOrProfile=-1; + if( m_leaderboard.m_currentEntryCount > 0 ) + { + unsigned int selection = (unsigned int)m_listGamers.GetCurSel(); + + // if the selected user is me, don't show Send Friend Request, and show the gamer profile, not the gamer card + + // Check that the index is actually within range of the data we've got before accessing the m_leaderboard.m_entries array + int idx = selection - (m_leaderboard.m_entryStartIndex-1); + if( ( idx < 0 ) || ( idx >= NUM_ENTRIES ) ) + { + return; + } + if(m_leaderboard.m_entries[idx].m_bPlayer) + { + iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERPROFILE; + } + else + { + iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERCARD; + // if we're on the friends filter, then don't show the Send Friend Request + bool bIsFriend = m_currentFilter == LeaderboardManager::eFM_Friends; + + if(!bIsFriend) + { + // check the entry we're on + if( m_leaderboard.m_currentEntryCount > 0 ) + { + if( selection >= m_leaderboard.m_entryStartIndex-1 && + selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) ) + { + if( (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bFriend==false) && (m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_bRequestedFriend==false)) + { + iTooltipFriendRequest=IDS_TOOLTIPS_SEND_FRIEND_REQUEST; + } + } + } + } + } + } + + // 4J-PB - no room on the screen for the LT/RT prompt + /* + if(m_leaderboard.m_currentEntryCount>11) + { + ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile, IDS_TOOLTIPS_PAGEUP, IDS_TOOLTIPS_PAGEDOWN); + } + else*/ + { + ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile); + } +} + +HRESULT CScene_Leaderboards::OnKeyDown(XUIMessageInput* pInputData, BOOL& bHandled) +{ + ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode); + + switch(pInputData->dwKeyCode) + { + case VK_PAD_RSHOULDER: + case VK_PAD_LSHOULDER: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if(m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + if( pInputData->dwKeyCode == VK_PAD_RSHOULDER ) + { + ++m_currentDifficulty; + if( m_currentDifficulty == 4 ) + m_currentDifficulty = 0; + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 1; + } + else + { + if( m_currentDifficulty == 0 ) + m_currentDifficulty = 4; + --m_currentDifficulty; + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 3; + } + + SetLeaderboardHeader(); + ClearLeaderboardTitlebar(); + + ReadStats(-1); + CXuiSceneBase::PlayUISFX(eSFX_Press); + } + + bHandled = TRUE; + } + break; + case VK_PAD_LTHUMB_RIGHT: + case VK_PAD_LTHUMB_LEFT: + case VK_PAD_DPAD_LEFT: + case VK_PAD_DPAD_RIGHT: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if ( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + m_bReady=false; + if(( pInputData->dwKeyCode == VK_PAD_LTHUMB_RIGHT ) ||(pInputData->dwKeyCode == VK_PAD_DPAD_RIGHT)) + { + ++m_currentLeaderboard; + if( m_currentLeaderboard == NUM_LEADERBOARDS ) + m_currentLeaderboard = 0; + } + else + { + if( m_currentLeaderboard == 0 ) + m_currentLeaderboard = NUM_LEADERBOARDS; + --m_currentLeaderboard; + } + + if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 ) + m_currentDifficulty = 1; + + SetLeaderboardHeader(); + ClearLeaderboardTitlebar(); + + + ReadStats(-1); + CXuiSceneBase::PlayUISFX(eSFX_Press); + } + bHandled = TRUE; + } + break; + case VK_PAD_LTRIGGER: + case VK_PAD_RTRIGGER: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + if( m_leaderboard.m_totalEntryCount <= 10 ) + break; + + if( pInputData->dwKeyCode == VK_PAD_LTRIGGER ) + { + m_newTop = m_listGamers.GetTopItem() - 10; + if( m_newTop < 0 ) + m_newTop = 0; + + m_newSel = m_newTop; + } + else + { + m_newTop = m_listGamers.GetTopItem() + 10; + if( m_newTop+10 > (int)m_leaderboard.m_totalEntryCount ) + { + m_newTop = m_leaderboard.m_totalEntryCount - 10; + if( m_newTop < 0 ) + m_newTop = 0; + } + + m_newSel = m_newTop; + } + //CXuiSceneBase::PlayUISFX(eSFX_Press); + } + bHandled = TRUE; + } + break; + case VK_PAD_X: + { + //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests + if( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() ) + { + switch( m_currentFilter ) + { + case LeaderboardManager::eFM_Friends: + { + m_currentFilter = LeaderboardManager::eFM_MyScore; + wchar_t filterBuffer[40]; + swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_MYSCORE)); + m_textFilter.SetText(filterBuffer); + } + break; + case LeaderboardManager::eFM_MyScore: + { + m_currentFilter = LeaderboardManager::eFM_TopRank; + wchar_t filterBuffer[40]; + swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_OVERALL)); + m_textFilter.SetText(filterBuffer); + } + break; + case LeaderboardManager::eFM_TopRank: + { + m_currentFilter = LeaderboardManager::eFM_Friends; + wchar_t filterBuffer[40]; + swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS)); + m_textFilter.SetText(filterBuffer); + } + break; + } + + ReadStats(-1); + CXuiSceneBase::PlayUISFX(eSFX_Press); + } + bHandled = TRUE; + } + break; + case VK_PAD_Y: + { + //Show gamercard + if( m_leaderboard.m_currentEntryCount > 0 ) + { + unsigned int selection = (unsigned int)m_listGamers.GetCurSel(); + if( selection >= m_leaderboard.m_entryStartIndex-1 && + selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) ) + { + PlayerUID xuid = m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_xuid; + if( xuid != INVALID_XUID ) + { + XShowGamerCardUI(ProfileManager.GetLockedProfile(), xuid); + CXuiSceneBase::PlayUISFX(eSFX_Press); + } + } + } + bHandled = TRUE; + } + break; + case VK_PAD_A: + { + //Send friend request if the filter mode is not friend, and they're not a friend or a pending friend + if( m_currentFilter != LeaderboardManager::eFM_Friends ) + { + if( m_leaderboard.m_currentEntryCount > 0 ) + { + unsigned int selection = (unsigned int)m_listGamers.GetCurSel(); + if( selection >= m_leaderboard.m_entryStartIndex-1 && + selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) ) + { + //If not the player and neither currently a friend or requested to be a friend + if( !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bPlayer && + !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bFriend && + !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bRequestedFriend ) + { + PlayerUID xuid = m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_xuid; + if( xuid != INVALID_XUID ) + { + XShowFriendRequestUI(ProfileManager.GetLockedProfile(), xuid); + CXuiSceneBase::PlayUISFX(eSFX_Press); + } + } + } + } + } + bHandled = TRUE; + } + break; + case VK_PAD_B: + case VK_ESCAPE: + { + BYTE userIndex = pInputData->UserIndex; + if( !app.IsPauseMenuDisplayed(userIndex) ) + { + // If we are not from a pause menu, then we are from the main menu + userIndex = XUSER_INDEX_ANY; + } + + app.NavigateBack(userIndex); + bHandled = TRUE; + } + break; + } + return S_OK; +} + +// DELETING // +#if 0 +void CScene_Leaderboards::GetFriends() +{ + DWORD resultsSize; + HANDLE hEnumerator; + DWORD ret; + + m_numFriends = 0; + + //First, get a list of (up to 100) friends (this is the maximum that the enumerator currently supports) + ret = XFriendsCreateEnumerator( ProfileManager.GetLockedProfile(), 0, 100, &resultsSize, &hEnumerator); + if( ret != ERROR_SUCCESS ) + return; + + m_friends = (XONLINE_FRIEND*) new BYTE[ resultsSize ]; + DWORD numFriends; + + ret = XEnumerate( + hEnumerator, + m_friends, + resultsSize, + &numFriends, + NULL ); + + if( ret != ERROR_SUCCESS ) + numFriends = 0; + + m_numFriends = numFriends; + + m_filteredFriends = new PlayerUID[m_numFriends+1]; + + m_numFilteredFriends = 0; + for( unsigned int friendIndex=0 ; friendIndex<numFriends ; ++friendIndex ) + { + if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 ) + { + m_filteredFriends[m_numFilteredFriends++] = m_friends[friendIndex].xuid; + } + } + m_filteredFriends[m_numFilteredFriends++] = LeaderboardManager::Instance()->GetMyXUID(); +} +#endif + +void CScene_Leaderboards::ReadStats(int startIndex) +{ + //If startIndex == -1, then use default values + if( startIndex == -1 ) + { + m_newEntryIndex = 1; + m_newReadSize = READ_SIZE; + + m_leaderboard.m_totalEntryCount = 0; + m_leaderboard.m_currentEntryCount = 0; + + m_listGamers.DeleteItems(0, m_listGamers.GetItemCount()); + } + else + { + m_newEntryIndex = (unsigned int)startIndex; + m_newReadSize = min((int)READ_SIZE, (int)m_leaderboard.m_totalEntryCount-(startIndex-1)); + } + + //Setup the spec structure for the read request + /* XUSER_STATS_SPEC* spec = new XUSER_STATS_SPEC[1]; // 4j-jev, moved into xboxLeaderboardManager + spec[0].dwViewId = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId; + spec[0].dwNumColumnIds = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount; + for( unsigned int i=0 ; i<spec[0].dwNumColumnIds ; ++i ) + spec[0].rgwColumnIds[i] = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnIds[i]; */ + + /*//This call takes ownership of spec and will free it when done + LeaderboardManager::Instance()->ReadStats( + m_newEntryIndex, + m_newReadSize, + 1, + spec, + (startIndex == -1) ? m_currentFilter : LeaderboardManager::eFM_TopRank, + CScene_Leaderboards::OnStatsReadComplete, + reinterpret_cast<void*>(this), + m_numFilteredFriends, + m_filteredFriends);*/ + + switch (startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank) + { + case LeaderboardManager::eFM_TopRank: + LeaderboardManager::Instance()->ReadStats_TopRank( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + m_newEntryIndex, m_newReadSize + ); + break; + case LeaderboardManager::eFM_MyScore: + LeaderboardManager::Instance()->ReadStats_MyScore( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + INVALID_XUID/*ignored*/, + m_newReadSize + ); + break; + case LeaderboardManager::eFM_Friends: + LeaderboardManager::Instance()->ReadStats_Friends( this, + m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard, + INVALID_XUID /*ignored*/, + 0 /*ignored*/, 0 /*ignored*/ + ); + break; + } + + //Show the loading message + m_textInfo.SetText(app.GetString(IDS_LEADERBOARD_LOADING)); + m_textInfo.SetShow(true); +} + +bool CScene_Leaderboards::OnStatsReadComplete(bool success, int numResults, LeaderboardManager::ViewOut results) +{ + //CScene_Leaderboards* scene = reinterpret_cast<CScene_Leaderboards*>(userdata); + + m_isProcessingStatsRead = true; + + //bool noResults = LeaderboardManager::Instance()->GetStatsState() != XboxLeaderboardManager::eStatsState_Ready; + bool ret; + + if (success) + { + m_numStats = numResults; + m_stats = results; + ret = RetrieveStats(); + } + else ret = true; + + //else LeaderboardManager::Instance()->SetStatsRetrieved(false); + + PopulateLeaderboard(!success); + + m_isProcessingStatsRead = false; + + return ret; +} + + +bool CScene_Leaderboards::RetrieveStats() +{ + + if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards))) + { + m_leaderboard.m_totalEntryCount = NUM_ENTRIES; + m_leaderboard.m_currentEntryCount = NUM_ENTRIES; + m_leaderboard.m_entryStartIndex = 1; + m_leaderboard.m_numColumns = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount; + + //For each entry in the leaderboard + for( unsigned int entryIndex=0 ; entryIndex<m_leaderboard.m_currentEntryCount ; entryIndex++ ) + { + m_leaderboard.m_entries[entryIndex].m_xuid = INVALID_XUID; + + m_leaderboard.m_entries[entryIndex].m_rank = entryIndex+1; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcRank, 12, L"12345678");//(int)m_leaderboard.m_entries[entryIndex].m_rank); + + swprintf(m_leaderboard.m_entries[entryIndex].m_gamerTag, 17, L"WWWWWWWWWWWWWWWW"); + + //m_leaderboard.m_entries[entryIndex].m_locale = (entryIndex % 37) + 1; + + bool isDistanceLeaderboard = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId == STATS_VIEW_TRAVELLING_PEACEFUL || LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId == STATS_VIEW_TRAVELLING_EASY || LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId == STATS_VIEW_TRAVELLING_NORMAL || LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId == STATS_VIEW_TRAVELLING_HARD; + + for( unsigned int i=0 ; i<m_leaderboard.m_numColumns ; i++ ) + { + if( !isDistanceLeaderboard ) + { + m_leaderboard.m_entries[entryIndex].m_columns[i] = USHRT_MAX; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%u", m_leaderboard.m_entries[entryIndex].m_columns[i]); + } + else + { + m_leaderboard.m_entries[entryIndex].m_columns[i] = UINT_MAX; + swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%.1fkm", ((float)m_leaderboard.m_entries[entryIndex].m_columns[i])/100.f/1000.f); + } + } + + m_leaderboard.m_entries[entryIndex].m_bPlayer = (entryIndex == 0); + m_leaderboard.m_entries[entryIndex].m_bOnline = (entryIndex != 0); + m_leaderboard.m_entries[entryIndex].m_bFriend = (entryIndex != 0); + m_leaderboard.m_entries[entryIndex].m_bRequestedFriend = false; + } + + //LeaderboardManager::Instance()->SetStatsRetrieved(true); + + return true; + } + + //assert( LeaderboardManager::Instance()->GetStats() != NULL ); + //PXUSER_STATS_READ_RESULTS stats = LeaderboardManager::Instance()->GetStats(); + //if( m_currentFilter == LeaderboardManager::eFM_Friends ) LeaderboardManager::Instance()->SortFriendStats(); + + bool isDistanceLeaderboard = m_stats->pViews[0].dwViewId == STATS_VIEW_TRAVELLING_PEACEFUL || m_stats->pViews[0].dwViewId == STATS_VIEW_TRAVELLING_EASY || m_stats->pViews[0].dwViewId == STATS_VIEW_TRAVELLING_NORMAL || m_stats->pViews[0].dwViewId == STATS_VIEW_TRAVELLING_HARD; + + //First read + if( m_leaderboard.m_totalEntryCount == 0 ) + { + m_leaderboard.m_totalEntryCount = (m_currentFilter == LeaderboardManager::eFM_Friends) ? m_stats->pViews[0].dwNumRows : m_stats->pViews[0].dwTotalViewRows; + m_leaderboard.m_currentEntryCount = m_stats->pViews[0].dwNumRows; + + if( m_leaderboard.m_totalEntryCount == 0 || m_leaderboard.m_currentEntryCount == 0 ) + { + //LeaderboardManager::Instance()->SetStatsRetrieved(false); + return false; + } + + m_leaderboard.m_numColumns = m_stats->pViews[0].pRows[0].dwNumColumns; + + m_leaderboard.m_entryStartIndex = (m_currentFilter == LeaderboardManager::eFM_Friends) ? 1 : m_stats->pViews[0].pRows[0].dwRank; + + for( unsigned int entryIndex=0 ; entryIndex<m_leaderboard.m_currentEntryCount ; ++entryIndex ) + CopyLeaderboardEntry(&(m_stats->pViews[0].pRows[entryIndex]), &(m_leaderboard.m_entries[entryIndex]), isDistanceLeaderboard); + + //If the filter mode is "My Score" then centre the list around the entries and select the player's score + if( m_currentFilter == LeaderboardManager::eFM_MyScore ) + { + //Centre the leaderboard list on the entries + m_newTop = m_leaderboard.m_entryStartIndex-1; + + //Select the player entry + for( unsigned int i=m_leaderboard.m_entryStartIndex ; i<m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount ; ++i ) + if( m_leaderboard.m_entries[i-m_leaderboard.m_entryStartIndex].m_bPlayer ) + { + m_newSel = i-1; // this might be off the screen! + // and reposition the top one + if(m_newSel-m_newTop>9) + { + m_newTop=m_newSel-9; + } + break; + } + } + } + //Additional read + else + { + unsigned int insertPosition = 0; + + //If the first new entry is at a smaller index than the current first entry + if( m_newEntryIndex < m_leaderboard.m_entryStartIndex ) + { + if( (m_leaderboard.m_entryStartIndex-1) < m_newReadSize ) + m_newReadSize = m_leaderboard.m_entryStartIndex-1; + + //Move current entries forward + memmove((void*)(m_leaderboard.m_entries+m_newReadSize), (void*)m_leaderboard.m_entries, sizeof(LeaderboardEntry)*(NUM_ENTRIES-m_newReadSize)); + + //Set the (now smaller) entry start index + m_leaderboard.m_entryStartIndex = m_newEntryIndex; + + //We will be inserting the new entries at the start of the array + insertPosition = 0; + + //Entry count is either max possible entries or current entry count + read size, whichever is smaller + m_leaderboard.m_currentEntryCount = min((int)NUM_ENTRIES, (int)(m_leaderboard.m_currentEntryCount+m_newReadSize)); + } + //If the last new entry is at a greater position than the last possible entry + else if( m_newEntryIndex+m_newReadSize-1 >= m_leaderboard.m_entryStartIndex+NUM_ENTRIES ) + { + //Calculate the overlap (this is by how much new entries would overhang the end of the array) + int overlap = (((m_newEntryIndex-1)+m_newReadSize-1) - (m_leaderboard.m_entryStartIndex-1)) - NUM_ENTRIES + 1; + + //Move current entries backwards + memmove((void*)m_leaderboard.m_entries, (void*)(m_leaderboard.m_entries+overlap), sizeof(LeaderboardEntry)*(NUM_ENTRIES-overlap)); + + //Set the (now larger) start index + m_leaderboard.m_entryStartIndex += overlap; + + //We will be inserting the new entries at the end of the array + insertPosition = NUM_ENTRIES - m_newReadSize; + + //Entry count is max possible entries + m_leaderboard.m_currentEntryCount = NUM_ENTRIES; + } + //Otherwise we're inserting at the end of the array and there is plenty of room + else + { + insertPosition = m_leaderboard.m_currentEntryCount; + m_leaderboard.m_currentEntryCount += m_newReadSize; + } + + //For each entry in the leaderboard + for( unsigned int entryIndex=0 ; entryIndex<m_newReadSize ; ++entryIndex ) + { + CopyLeaderboardEntry(&(m_stats->pViews[0].pRows[entryIndex]), &(m_leaderboard.m_entries[insertPosition]), isDistanceLeaderboard); + insertPosition++; + } + } + + //LeaderboardManager::Instance()->SetStatsRetrieved(true); + return true; +} + +HRESULT CScene_Leaderboards::OnGetItemCountAll(XUIMessageGetItemCount *pGetItemCountData, BOOL& bHandled) +{ + pGetItemCountData->cItems = m_leaderboard.m_totalEntryCount; + + //if(LeaderboardManager::Instance()->GetStatsRead()) + //{ + // m_bReady=true; + //} + bHandled = TRUE; + + return S_OK; +} + +HRESULT CScene_Leaderboards::OnGetSourceDataText(XUIMessageGetSourceText *pGetSourceTextData,BOOL& bHandled) +{ + if( pGetSourceTextData->bItemData ) + { + if( m_newTop != -1 && m_newSel != -1 ) + { + HRESULT ret = m_listGamers.SetTopItem(m_newTop); + assert( ret == S_OK ); + + ret = m_listGamers.SetCurSel(m_newSel); + assert( ret == S_OK ); + + // update the tooltips + + m_newTop = m_newSel = -1; + + bHandled = true; + return S_OK; + } + + unsigned int item = pGetSourceTextData->iItem; + + if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < m_leaderboard.m_entryStartIndex ) + { + if( LeaderboardManager::Instance()->isIdle() ) + { + int readIndex = m_leaderboard.m_entryStartIndex - READ_SIZE; + if( readIndex <= 0 ) + readIndex = 1; + assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount ); + ReadStats(readIndex); + } + } + else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount) ) + { + if( LeaderboardManager::Instance()->isIdle() ) + { + int readIndex = m_leaderboard.m_entryStartIndex + m_leaderboard.m_currentEntryCount; + assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount ); + ReadStats(readIndex); + } + } + else + { + unsigned int index = item - (m_leaderboard.m_entryStartIndex-1); + if( 0 == pGetSourceTextData->iData ) + { + pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_wcRank; + bHandled = TRUE; + } + else if( 1 == pGetSourceTextData->iData ) + { + pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_gamerTag; + bHandled = TRUE; + } + else if( pGetSourceTextData->iData >= 3 && pGetSourceTextData->iData <= 9 ) + { + if( m_leaderboard.m_numColumns <= (unsigned int)(pGetSourceTextData->iData-3) ) + pGetSourceTextData->szText = L""; + else + pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_wcColumns[pGetSourceTextData->iData-3]; + bHandled = TRUE; + } + } + } + return S_OK; +} + +HRESULT CScene_Leaderboards::OnGetSourceDataImage(XUIMessageGetSourceImage* pGetImage, BOOL& bHandled) +{ + if( (pGetImage->iData == 2) && (pGetImage->bItemData) ) + { + if( m_newTop != -1 && m_newSel != -1 ) + { + //Do nothing, alignment handled in OnGetSourceDataText + + bHandled = true; + return S_OK; + } + + unsigned int item = pGetImage->iItem; + if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < m_leaderboard.m_entryStartIndex ) + { + //Do nothing, reading handled in OnGetSourceDataText + } + else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount) ) + { + //Do nothing, reading handled in OnGetSourceDataText + } + // 4J-PB - we're not allowed to show flags any more +// else +// { +// unsigned int index = item - (m_leaderboard.m_entryStartIndex-1); +// if( m_leaderboard.m_entries[index].m_locale > 0 && m_leaderboard.m_entries[index].m_locale <= XC_LOCALE_RUSSIAN_FEDERATION ) +// pGetImage->szPath = FLAG_ICON_PATHS[ m_leaderboard.m_entries[index].m_locale-1 ]; +// bHandled = TRUE; +// } + } + + return S_OK; +} + +void CScene_Leaderboards::PopulateLeaderboard(bool noResults) +{ + HRESULT hr; + HXUIOBJ visual=NULL; + HXUIOBJ hTemp=NULL; + hr=XuiControlGetVisual(m_listGamers.m_hObj,&visual); + + if(m_pHTitleIconSlots[0]==NULL) + { + VOID *pObj; + HXUIOBJ button; + D3DXVECTOR3 vPos; + + for(int i=0;i<7;i++) + { + // retrieve the visual for the title icon + hr=XuiElementGetChildById(visual,m_TitleIconNameA[i],&button); + + XuiObjectFromHandle( button, &pObj ); + m_pHTitleIconSlots[i] = (CXuiCtrlCraftIngredientSlot *)pObj; + + // store the default position, since we'll be repositioning these depending on how many are valid for each board + m_pHTitleIconSlots[i]->GetPosition(&vPos); + m_fTitleIconXPositions[i]= vPos.x; + } + } + + int iValidSlots=SetLeaderboardTitleIcons(); + + if( !noResults && m_leaderboard.m_totalEntryCount > 0 ) + { + hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp); + if(hTemp) + { + XuiControlSetText(hTemp,app.GetString( IDS_LEADERBOARD_GAMERTAG )); + XuiElementSetShow(hTemp, TRUE); + } + hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp); + if(hTemp) + { + XuiControlSetText(hTemp,app.GetString( IDS_LEADERBOARD_RANK )); + XuiElementSetShow(hTemp, TRUE); + } + + //Update entries display + wchar_t entriesBuffer[40]; + if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards))) + { + swprintf(entriesBuffer, 40, L"%ls12345678", app.GetString(IDS_LEADERBOARD_ENTRIES)); + } + else + { + swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), m_leaderboard.m_totalEntryCount); + } + + m_textEntries.SetText(entriesBuffer); + + //Hide the loading message + m_textInfo.SetShow(false); + + //Add space for new entries + m_listGamers.InsertItems(0, m_leaderboard.m_totalEntryCount); + + // 4J Stu - Fix for leaderboards taking forever to update. Was looping over m_totalEntryCount which is ~2mil in + // some leaderboards in production atm. + // Changed to loop over the range of cached values, although even that is probably overkill. + // Really only the newly updated rows need changed, but this shouldn't cause any performance issues + for(DWORD i = m_leaderboard.m_entryStartIndex - 1; i < (m_leaderboard.m_entryStartIndex - 1) + m_leaderboard.m_currentEntryCount; ++i) + { + HXUIOBJ visual=NULL; + HXUIOBJ button; + D3DXVECTOR3 vPos; + // 4J-PB - fix for #13768 - Leaderboards: Player scores appear misaligned when viewed under the "My Score" leaderboard filter + HXUIOBJ hTop=m_listGamers.GetItemControl(i-(m_leaderboard.m_entryStartIndex - 1)); + HRESULT hr=XuiControlGetVisual(hTop,&visual); + + for(int j=0;j<7;j++) + { + hr=XuiElementGetChildById(visual,m_TextColumnNameA[j],&button); + m_hTextEntryA[j]=button; + + XuiElementGetPosition(button,&vPos); + m_fTextXPositions[j]=vPos.x; + } + RepositionText(iValidSlots); + } + + // hide empty icon boxes + for(int i = (LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount);i<7;i++) + { + m_pHTitleIconSlots[i]->SetShow(FALSE); + } + } + else + { + hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp); + if(hTemp) + { + XuiElementSetShow(hTemp, FALSE); + } + hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp); + if(hTemp) + { + XuiElementSetShow(hTemp, FALSE); + } + + //Update entries display (to zero) + wchar_t entriesBuffer[40]; + swprintf(entriesBuffer, 40, L"%ls0", app.GetString(IDS_LEADERBOARD_ENTRIES)); + m_textEntries.SetText(entriesBuffer); + + //Show the no results message + m_textInfo.SetText(app.GetString(IDS_LEADERBOARD_NORESULTS)); + m_textInfo.SetShow(true); + + // hide the icons + for(int i=0;i<7;i++) + { + m_pHTitleIconSlots[i]->SetShow(FALSE); + } + + } + + m_bPopulatedOnce = true; +} + +void CScene_Leaderboards::CopyLeaderboardEntry(PXUSER_STATS_ROW statsRow, LeaderboardEntry* leaderboardEntry, bool isDistanceLeaderboard) +{ + leaderboardEntry->m_xuid = statsRow->xuid; + + //Copy the rank + leaderboardEntry->m_rank = statsRow->dwRank; + DWORD displayRank = leaderboardEntry->m_rank; + if(displayRank > 9999999) displayRank = 9999999; + swprintf_s(leaderboardEntry->m_wcRank, 12, L"%u", displayRank); + + //strcpy(statsRow->szGamertag,"WWWWWWWWWWWWWWWW"); + + //Convert the gamertag from char to wchar_t + MultiByteToWideChar( + CP_UTF8, + 0, + statsRow->szGamertag, + strlen(statsRow->szGamertag), + leaderboardEntry->m_gamerTag, + XUSER_NAME_SIZE ); + //Null terminate the gamertag + leaderboardEntry->m_gamerTag[strlen(statsRow->szGamertag)] = L'\0'; + + //Copy the locale + //leaderboardEntry->m_locale = statsRow->pColumns[0].Value.nData; + + //Copy the other columns + for( unsigned int i=0 ; i<statsRow->dwNumColumns ; i++ ) + { + leaderboardEntry->m_columns[i] = statsRow->pColumns[i].Value.nData; + if( !isDistanceLeaderboard ) + { + DWORD displayValue = leaderboardEntry->m_columns[i]; + if(displayValue > 99999) displayValue = 99999; + swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%u",displayValue); +#ifdef _DEBUG + app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]); +#endif + } + else + { + // check how many digits we have + int iDigitC=0; + unsigned int uiVal=leaderboardEntry->m_columns[i]; +// uiVal=0xFFFFFFFF; +// leaderboardEntry->m_columns[i-1]=uiVal; + + while(uiVal!=0) + { + uiVal/=10; + iDigitC++; + } + +#ifdef _DEBUG + app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]); +#endif + if(iDigitC<4) + { + // m + swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%um", leaderboardEntry->m_columns[i]); +#ifdef _DEBUG + app.DebugPrintf("Display - %um\n", leaderboardEntry->m_columns[i]); +#endif + } + else if(iDigitC<8) + { + // km with a .X + swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%.1fkm", ((float)leaderboardEntry->m_columns[i])/1000.f); +#ifdef _DEBUG + app.DebugPrintf("Display - %.1fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f); +#endif + } + else + { + // bigger than that, so no decimal point + swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%.0fkm", ((float)leaderboardEntry->m_columns[i])/1000.f); +#ifdef _DEBUG + app.DebugPrintf("Display - %.0fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f); +#endif + } + } + } + + //Is the player + if( statsRow->xuid == ((XboxLeaderboardManager*)LeaderboardManager::Instance())->GetMyXUID() ) + { + leaderboardEntry->m_bPlayer = true; + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = false; + } + else + { + leaderboardEntry->m_bPlayer = false; + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = false; + + //Check for friend status + for( unsigned int friendIndex=0 ; friendIndex<m_numFriends ; ++friendIndex ) + { + if( m_friends[friendIndex].xuid == statsRow->xuid ) + { + if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 ) + { + //Is friend, might be online + leaderboardEntry->m_bFriend = true; + leaderboardEntry->m_bOnline = ( m_friends[friendIndex].dwFriendState & XONLINE_FRIENDSTATE_FLAG_ONLINE ); + leaderboardEntry->m_bRequestedFriend = false; + } + else + { + //Friend request sent but not accepted yet + leaderboardEntry->m_bOnline = false; + leaderboardEntry->m_bFriend = false; + leaderboardEntry->m_bRequestedFriend = true; + } + + break; + } + } + } +} + +void CScene_Leaderboards::SetLeaderboardHeader() +{ + WCHAR buffer[40]; + DWORD bufferLength = 40; + + DWORD ret = XResourceGetString(LEADERBOARD_HEADERS[m_currentLeaderboard][m_currentDifficulty], buffer, &bufferLength, NULL); + + if( ret == ERROR_SUCCESS ) + m_textLeaderboard.SetText(buffer); +} + +int CScene_Leaderboards::SetLeaderboardTitleIcons() +{ + int iValidIcons=0; + + for(int i=0;i<7;i++) + { + if(TitleIcons[m_currentLeaderboard][i]==0) + { + m_pHTitleIconSlots[i]->SetShow(FALSE); + } + else + { + iValidIcons++; + m_pHTitleIconSlots[i]->SetIcon(DEFAULT_XUI_MENU_USER,TitleIcons[m_currentLeaderboard][i],0,1,10,31,false,FALSE); + } + } + + Reposition(iValidIcons); + + return iValidIcons; +} +void CScene_Leaderboards::ClearLeaderboardTitlebar() +{ + for(int i=0;i<7;i++) + { + m_pHTitleIconSlots[i]->SetShow(FALSE); + } + + HXUIOBJ visual=NULL; + HXUIOBJ hTemp=NULL; + HRESULT hr; + hr=XuiControlGetVisual(m_listGamers.m_hObj,&visual); + + hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp); + if(hTemp) + { + XuiElementSetShow(hTemp, FALSE); + } + hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp); + if(hTemp) + { + XuiElementSetShow(hTemp, FALSE); + } +} |
