the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include <xuiresource.h>
3#include <xuiapp.h>
4#include "XUI_Leaderboards.h"
5#include "..\..\..\Minecraft.World\Tile.h"
6#include "..\..\..\Minecraft.World\Item.h"
7#include "XUI_Ctrl_CraftIngredientSlot.h"
8#include "XUI_XZP_Icons.h"
9
10LPCWSTR CScene_Leaderboards::m_TitleIconNameA[7]=
11{
12 L"XuiHSlot1",
13 L"XuiHSlot2",
14 L"XuiHSlot3",
15 L"XuiHSlot4",
16 L"XuiHSlot5",
17 L"XuiHSlot6",
18 L"XuiHSlot7",
19};
20
21LPCWSTR CScene_Leaderboards::m_TextColumnNameA[7]=
22{
23 L"text_Column1",
24 L"text_Column2",
25 L"text_Column3",
26 L"text_Column4",
27 L"text_Column5",
28 L"text_Column6",
29 L"text_Column7",
30};
31
32
33// if the value is greater than 511, it's an xzp icon that needs displayed, rather than the game icon
34const int CScene_Leaderboards::TitleIcons[CScene_Leaderboards::NUM_LEADERBOARDS][7] =
35{
36 { XZP_ICON_WALKED, XZP_ICON_FALLEN, Item::minecart_Id, Item::boat_Id, NULL },
37 { Tile::dirt_Id, Tile::stoneBrick_Id, Tile::sand_Id, Tile::rock_Id, Tile::gravel_Id, Tile::clay_Id, Tile::obsidian_Id },
38 { Item::egg_Id, Item::wheat_Id, Tile::mushroom1_Id, Tile::reeds_Id, Item::milk_Id, Tile::pumpkin_Id, NULL },
39 { XZP_ICON_ZOMBIE, XZP_ICON_SKELETON, XZP_ICON_CREEPER, XZP_ICON_SPIDER, XZP_ICON_SPIDERJOCKEY, XZP_ICON_ZOMBIEPIGMAN, XZP_ICON_SLIME },
40};
41
42const int CScene_Leaderboards::LEADERBOARD_HEADERS[CScene_Leaderboards::NUM_LEADERBOARDS][4] = {
43 { SPASTRING_LB_TRAVELLING_PEACEFUL_NAME, SPASTRING_LB_TRAVELLING_EASY_NAME, SPASTRING_LB_TRAVELLING_NORMAL_NAME, SPASTRING_LB_TRAVELLING_HARD_NAME },
44 { SPASTRING_LB_MINING_BLOCKS_PEACEFUL_NAME, SPASTRING_LB_MINING_BLOCKS_EASY_NAME, SPASTRING_LB_MINING_BLOCKS_NORMAL_NAME, SPASTRING_LB_MINING_BLOCKS_HARD_NAME },
45 { SPASTRING_LB_FARMING_PEACEFUL_NAME, SPASTRING_LB_FARMING_EASY_NAME, SPASTRING_LB_FARMING_NORMAL_NAME, SPASTRING_LB_FARMING_HARD_NAME },
46 { NULL, SPASTRING_LB_KILLS_EASY_NAME, SPASTRING_LB_KILLS_NORMAL_NAME, SPASTRING_LB_KILLS_HARD_NAME },
47};
48
49const CScene_Leaderboards::LeaderboardDescriptor CScene_Leaderboards::LEADERBOARD_DESCRIPTORS[CScene_Leaderboards::NUM_LEADERBOARDS][4] = {
50 {
51 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),
52 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),
53 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),
54 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),
55 },
56 {
57 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 ),
58 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 ),
59 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 ),
60 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 ),
61 },
62 {
63 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 ),
64 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 ),
65 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 ),
66 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 ),
67 },
68 {
69 CScene_Leaderboards::LeaderboardDescriptor( NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ),
70 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 ),
71 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 ),
72 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 ),
73 },
74};
75
76HRESULT CScene_Leaderboards::OnInit(XUIMessageInit *pInitData, BOOL &bHandled)
77{
78 m_iPad = *(int *)pInitData->pvInitData;
79 MapChildControls();
80 m_bReady=false;
81
82 // if we're not in the game, we need to use basescene 0
83 if(Minecraft::GetInstance()->level==NULL)
84 {
85 m_iPad=DEFAULT_XUI_MENU_USER;
86 }
87
88 m_bPopulatedOnce = false;
89
90 ui.SetTooltips(m_iPad,-1, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, -1);
91 CXuiSceneBase::ShowLogo( m_iPad, FALSE );
92
93 m_friends = NULL;
94 m_numFriends = 0;
95 m_filteredFriends = NULL;
96 m_numFilteredFriends = 0;
97
98 m_newTop = m_newSel = -1;
99
100 m_isProcessingStatsRead = false;
101
102 // Alert the app the we want to be informed of ethernet connections
103 app.SetLiveLinkRequired( true );
104
105 LeaderboardManager::Instance()->OpenSession();
106
107 //GetFriends();
108
109 m_currentLeaderboard = 0;
110 m_currentDifficulty = 2;
111 SetLeaderboardHeader();
112
113 m_currentFilter = LeaderboardManager::eFM_Friends;
114 wchar_t filterBuffer[40];
115 swprintf(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS));
116 m_textFilter.SetText(filterBuffer);
117
118 wchar_t entriesBuffer[40];
119 swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), 0);
120 m_textEntries.SetText(entriesBuffer);
121
122 ReadStats(-1);
123
124 // title icons
125 for(int i=0;i<7;i++)
126 {
127 m_pHTitleIconSlots[i]=NULL;
128 m_fTitleIconXPositions[i]=0.0f;
129 m_fTextXPositions[i]=0.0f;
130 m_hTextEntryA[i]=NULL;
131 }
132
133
134 bHandled = TRUE;
135 return S_OK;
136}
137
138
139void CScene_Leaderboards::Reposition(int iNumber)
140{
141 float fIconSize; // including gap
142 float fNewIconIncrement;
143 D3DXVECTOR3 vPos;
144
145 fIconSize=(m_fTitleIconXPositions[6]-m_fTitleIconXPositions[0])/6.0f;
146 fNewIconIncrement=(fIconSize*7.0f)/(float)iNumber;
147
148 // reposition the title icons based on the number there are
149 for(int i=0;i<iNumber;i++)
150 {
151 m_pHTitleIconSlots[i]->GetPosition(&vPos);
152 vPos.x=m_fTitleIconXPositions[0]+(((float)i)*fNewIconIncrement)+(fNewIconIncrement-fIconSize)/2.0f;
153 m_pHTitleIconSlots[i]->SetPosition(&vPos);
154 }
155}
156
157void CScene_Leaderboards::RepositionText(int iNumber)
158{
159 float fTextSize; // including gap
160 float fNewTextIncrement;
161 D3DXVECTOR3 vPos;
162
163 fTextSize=(m_fTextXPositions[6]-m_fTextXPositions[0])/6.0f;
164 fNewTextIncrement=(fTextSize*7.0f)/(float)iNumber;
165
166 // reposition the title icons based on the number there are
167 for(int i=0;i<iNumber;i++)
168 {
169 // and reposition the text
170 XuiElementGetPosition(m_hTextEntryA[i],&vPos);
171 vPos.x=m_fTextXPositions[0]+(((float)i)*fNewTextIncrement);
172 XuiElementSetPosition(m_hTextEntryA[i],&vPos);
173 // and change the size
174 float fWidth,fHeight;
175 XuiElementGetBounds(m_hTextEntryA[i],&fWidth,&fHeight);
176 XuiElementSetBounds(m_hTextEntryA[i],fNewTextIncrement,fHeight);
177 }
178}
179
180HRESULT CScene_Leaderboards::OnDestroy()
181{
182 LeaderboardManager::Instance()->CancelOperation();
183 LeaderboardManager::Instance()->CloseSession();
184
185 // Alert the app the we no longer want to be informed of ethernet connections
186 app.SetLiveLinkRequired( false );
187
188 while( m_isProcessingStatsRead )
189 {
190 Sleep( 10 );
191 }
192
193 if( m_friends != NULL )
194 delete [] m_friends;
195
196 if( m_filteredFriends != NULL )
197 delete [] m_filteredFriends;
198
199 return S_OK;
200}
201
202HRESULT CScene_Leaderboards::OnNotifySetFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled)
203{
204 UpdateTooltips();
205 return S_OK;
206}
207
208HRESULT CScene_Leaderboards::OnNotifySelChanged(HXUIOBJ hObjSource, XUINotifySelChanged *pNotifySelChangedData, BOOL& bHandled)
209{
210
211 if(m_bReady && pNotifySelChangedData->iOldItem!=-1)
212 {
213 CXuiSceneBase::PlayUISFX(eSFX_Focus);
214 }
215
216 return S_OK;
217}
218
219void CScene_Leaderboards::UpdateTooltips()
220{
221 int iTooltipFriendRequest=-1;
222 int iTooltipGamerCardOrProfile=-1;
223 if( m_leaderboard.m_currentEntryCount > 0 )
224 {
225 unsigned int selection = (unsigned int)m_listGamers.GetCurSel();
226
227 // if the selected user is me, don't show Send Friend Request, and show the gamer profile, not the gamer card
228
229 // Check that the index is actually within range of the data we've got before accessing the m_leaderboard.m_entries array
230 int idx = selection - (m_leaderboard.m_entryStartIndex-1);
231 if( ( idx < 0 ) || ( idx >= NUM_ENTRIES ) )
232 {
233 return;
234 }
235 if(m_leaderboard.m_entries[idx].m_bPlayer)
236 {
237 iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERPROFILE;
238 }
239 else
240 {
241 iTooltipGamerCardOrProfile=IDS_TOOLTIPS_VIEW_GAMERCARD;
242 // if we're on the friends filter, then don't show the Send Friend Request
243 bool bIsFriend = m_currentFilter == LeaderboardManager::eFM_Friends;
244
245 if(!bIsFriend)
246 {
247 // check the entry we're on
248 if( m_leaderboard.m_currentEntryCount > 0 )
249 {
250 if( selection >= m_leaderboard.m_entryStartIndex-1 &&
251 selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) )
252 {
253 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))
254 {
255 iTooltipFriendRequest=IDS_TOOLTIPS_SEND_FRIEND_REQUEST;
256 }
257 }
258 }
259 }
260 }
261 }
262
263 // 4J-PB - no room on the screen for the LT/RT prompt
264 /*
265 if(m_leaderboard.m_currentEntryCount>11)
266 {
267 ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile, IDS_TOOLTIPS_PAGEUP, IDS_TOOLTIPS_PAGEDOWN);
268 }
269 else*/
270 {
271 ui.SetTooltips(m_iPad, iTooltipFriendRequest, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGE_FILTER, iTooltipGamerCardOrProfile);
272 }
273}
274
275HRESULT CScene_Leaderboards::OnKeyDown(XUIMessageInput* pInputData, BOOL& bHandled)
276{
277 ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode);
278
279 switch(pInputData->dwKeyCode)
280 {
281 case VK_PAD_RSHOULDER:
282 case VK_PAD_LSHOULDER:
283 {
284 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
285 if(m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
286 {
287 if( pInputData->dwKeyCode == VK_PAD_RSHOULDER )
288 {
289 ++m_currentDifficulty;
290 if( m_currentDifficulty == 4 )
291 m_currentDifficulty = 0;
292
293 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
294 m_currentDifficulty = 1;
295 }
296 else
297 {
298 if( m_currentDifficulty == 0 )
299 m_currentDifficulty = 4;
300 --m_currentDifficulty;
301
302 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
303 m_currentDifficulty = 3;
304 }
305
306 SetLeaderboardHeader();
307 ClearLeaderboardTitlebar();
308
309 ReadStats(-1);
310 CXuiSceneBase::PlayUISFX(eSFX_Press);
311 }
312
313 bHandled = TRUE;
314 }
315 break;
316 case VK_PAD_LTHUMB_RIGHT:
317 case VK_PAD_LTHUMB_LEFT:
318 case VK_PAD_DPAD_LEFT:
319 case VK_PAD_DPAD_RIGHT:
320 {
321 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
322 if ( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
323 {
324 m_bReady=false;
325 if(( pInputData->dwKeyCode == VK_PAD_LTHUMB_RIGHT ) ||(pInputData->dwKeyCode == VK_PAD_DPAD_RIGHT))
326 {
327 ++m_currentLeaderboard;
328 if( m_currentLeaderboard == NUM_LEADERBOARDS )
329 m_currentLeaderboard = 0;
330 }
331 else
332 {
333 if( m_currentLeaderboard == 0 )
334 m_currentLeaderboard = NUM_LEADERBOARDS;
335 --m_currentLeaderboard;
336 }
337
338 if( m_currentLeaderboard == LEADERBOARD_KILLS_POSITION && m_currentDifficulty == 0 )
339 m_currentDifficulty = 1;
340
341 SetLeaderboardHeader();
342 ClearLeaderboardTitlebar();
343
344
345 ReadStats(-1);
346 CXuiSceneBase::PlayUISFX(eSFX_Press);
347 }
348 bHandled = TRUE;
349 }
350 break;
351 case VK_PAD_LTRIGGER:
352 case VK_PAD_RTRIGGER:
353 {
354 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
355 if( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
356 {
357 if( m_leaderboard.m_totalEntryCount <= 10 )
358 break;
359
360 if( pInputData->dwKeyCode == VK_PAD_LTRIGGER )
361 {
362 m_newTop = m_listGamers.GetTopItem() - 10;
363 if( m_newTop < 0 )
364 m_newTop = 0;
365
366 m_newSel = m_newTop;
367 }
368 else
369 {
370 m_newTop = m_listGamers.GetTopItem() + 10;
371 if( m_newTop+10 > (int)m_leaderboard.m_totalEntryCount )
372 {
373 m_newTop = m_leaderboard.m_totalEntryCount - 10;
374 if( m_newTop < 0 )
375 m_newTop = 0;
376 }
377
378 m_newSel = m_newTop;
379 }
380 //CXuiSceneBase::PlayUISFX(eSFX_Press);
381 }
382 bHandled = TRUE;
383 }
384 break;
385 case VK_PAD_X:
386 {
387 //Do nothing if a stats read is currently in progress, otherwise the system complains about to many read requests
388 if( m_bPopulatedOnce && LeaderboardManager::Instance()->isIdle() )
389 {
390 switch( m_currentFilter )
391 {
392 case LeaderboardManager::eFM_Friends:
393 {
394 m_currentFilter = LeaderboardManager::eFM_MyScore;
395 wchar_t filterBuffer[40];
396 swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_MYSCORE));
397 m_textFilter.SetText(filterBuffer);
398 }
399 break;
400 case LeaderboardManager::eFM_MyScore:
401 {
402 m_currentFilter = LeaderboardManager::eFM_TopRank;
403 wchar_t filterBuffer[40];
404 swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_OVERALL));
405 m_textFilter.SetText(filterBuffer);
406 }
407 break;
408 case LeaderboardManager::eFM_TopRank:
409 {
410 m_currentFilter = LeaderboardManager::eFM_Friends;
411 wchar_t filterBuffer[40];
412 swprintf_s(filterBuffer, 40, L"%ls%ls", app.GetString(IDS_LEADERBOARD_FILTER), app.GetString(IDS_LEADERBOARD_FILTER_FRIENDS));
413 m_textFilter.SetText(filterBuffer);
414 }
415 break;
416 }
417
418 ReadStats(-1);
419 CXuiSceneBase::PlayUISFX(eSFX_Press);
420 }
421 bHandled = TRUE;
422 }
423 break;
424 case VK_PAD_Y:
425 {
426 //Show gamercard
427 if( m_leaderboard.m_currentEntryCount > 0 )
428 {
429 unsigned int selection = (unsigned int)m_listGamers.GetCurSel();
430 if( selection >= m_leaderboard.m_entryStartIndex-1 &&
431 selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) )
432 {
433 PlayerUID xuid = m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1)].m_xuid;
434 if( xuid != INVALID_XUID )
435 {
436 XShowGamerCardUI(ProfileManager.GetLockedProfile(), xuid);
437 CXuiSceneBase::PlayUISFX(eSFX_Press);
438 }
439 }
440 }
441 bHandled = TRUE;
442 }
443 break;
444 case VK_PAD_A:
445 {
446 //Send friend request if the filter mode is not friend, and they're not a friend or a pending friend
447 if( m_currentFilter != LeaderboardManager::eFM_Friends )
448 {
449 if( m_leaderboard.m_currentEntryCount > 0 )
450 {
451 unsigned int selection = (unsigned int)m_listGamers.GetCurSel();
452 if( selection >= m_leaderboard.m_entryStartIndex-1 &&
453 selection < (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount-1) )
454 {
455 //If not the player and neither currently a friend or requested to be a friend
456 if( !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bPlayer &&
457 !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bFriend &&
458 !m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_bRequestedFriend )
459 {
460 PlayerUID xuid = m_leaderboard.m_entries[selection - (m_leaderboard.m_entryStartIndex-1) ].m_xuid;
461 if( xuid != INVALID_XUID )
462 {
463 XShowFriendRequestUI(ProfileManager.GetLockedProfile(), xuid);
464 CXuiSceneBase::PlayUISFX(eSFX_Press);
465 }
466 }
467 }
468 }
469 }
470 bHandled = TRUE;
471 }
472 break;
473 case VK_PAD_B:
474 case VK_ESCAPE:
475 {
476 BYTE userIndex = pInputData->UserIndex;
477 if( !app.IsPauseMenuDisplayed(userIndex) )
478 {
479 // If we are not from a pause menu, then we are from the main menu
480 userIndex = XUSER_INDEX_ANY;
481 }
482
483 app.NavigateBack(userIndex);
484 bHandled = TRUE;
485 }
486 break;
487 }
488 return S_OK;
489}
490
491// DELETING //
492#if 0
493void CScene_Leaderboards::GetFriends()
494{
495 DWORD resultsSize;
496 HANDLE hEnumerator;
497 DWORD ret;
498
499 m_numFriends = 0;
500
501 //First, get a list of (up to 100) friends (this is the maximum that the enumerator currently supports)
502 ret = XFriendsCreateEnumerator( ProfileManager.GetLockedProfile(), 0, 100, &resultsSize, &hEnumerator);
503 if( ret != ERROR_SUCCESS )
504 return;
505
506 m_friends = (XONLINE_FRIEND*) new BYTE[ resultsSize ];
507 DWORD numFriends;
508
509 ret = XEnumerate(
510 hEnumerator,
511 m_friends,
512 resultsSize,
513 &numFriends,
514 NULL );
515
516 if( ret != ERROR_SUCCESS )
517 numFriends = 0;
518
519 m_numFriends = numFriends;
520
521 m_filteredFriends = new PlayerUID[m_numFriends+1];
522
523 m_numFilteredFriends = 0;
524 for( unsigned int friendIndex=0 ; friendIndex<numFriends ; ++friendIndex )
525 {
526 if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 )
527 {
528 m_filteredFriends[m_numFilteredFriends++] = m_friends[friendIndex].xuid;
529 }
530 }
531 m_filteredFriends[m_numFilteredFriends++] = LeaderboardManager::Instance()->GetMyXUID();
532}
533#endif
534
535void CScene_Leaderboards::ReadStats(int startIndex)
536{
537 //If startIndex == -1, then use default values
538 if( startIndex == -1 )
539 {
540 m_newEntryIndex = 1;
541 m_newReadSize = READ_SIZE;
542
543 m_leaderboard.m_totalEntryCount = 0;
544 m_leaderboard.m_currentEntryCount = 0;
545
546 m_listGamers.DeleteItems(0, m_listGamers.GetItemCount());
547 }
548 else
549 {
550 m_newEntryIndex = (unsigned int)startIndex;
551 m_newReadSize = min((int)READ_SIZE, (int)m_leaderboard.m_totalEntryCount-(startIndex-1));
552 }
553
554 //Setup the spec structure for the read request
555 /* XUSER_STATS_SPEC* spec = new XUSER_STATS_SPEC[1]; // 4j-jev, moved into xboxLeaderboardManager
556 spec[0].dwViewId = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_viewId;
557 spec[0].dwNumColumnIds = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount;
558 for( unsigned int i=0 ; i<spec[0].dwNumColumnIds ; ++i )
559 spec[0].rgwColumnIds[i] = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnIds[i]; */
560
561 /*//This call takes ownership of spec and will free it when done
562 LeaderboardManager::Instance()->ReadStats(
563 m_newEntryIndex,
564 m_newReadSize,
565 1,
566 spec,
567 (startIndex == -1) ? m_currentFilter : LeaderboardManager::eFM_TopRank,
568 CScene_Leaderboards::OnStatsReadComplete,
569 reinterpret_cast<void*>(this),
570 m_numFilteredFriends,
571 m_filteredFriends);*/
572
573 switch (startIndex == -1 ? m_currentFilter : LeaderboardManager::eFM_TopRank)
574 {
575 case LeaderboardManager::eFM_TopRank:
576 LeaderboardManager::Instance()->ReadStats_TopRank( this,
577 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
578 m_newEntryIndex, m_newReadSize
579 );
580 break;
581 case LeaderboardManager::eFM_MyScore:
582 LeaderboardManager::Instance()->ReadStats_MyScore( this,
583 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
584 INVALID_XUID/*ignored*/,
585 m_newReadSize
586 );
587 break;
588 case LeaderboardManager::eFM_Friends:
589 LeaderboardManager::Instance()->ReadStats_Friends( this,
590 m_currentDifficulty, (LeaderboardManager::EStatsType) m_currentLeaderboard,
591 INVALID_XUID /*ignored*/,
592 0 /*ignored*/, 0 /*ignored*/
593 );
594 break;
595 }
596
597 //Show the loading message
598 m_textInfo.SetText(app.GetString(IDS_LEADERBOARD_LOADING));
599 m_textInfo.SetShow(true);
600}
601
602bool CScene_Leaderboards::OnStatsReadComplete(bool success, int numResults, LeaderboardManager::ViewOut results)
603{
604 //CScene_Leaderboards* scene = reinterpret_cast<CScene_Leaderboards*>(userdata);
605
606 m_isProcessingStatsRead = true;
607
608 //bool noResults = LeaderboardManager::Instance()->GetStatsState() != XboxLeaderboardManager::eStatsState_Ready;
609 bool ret;
610
611 if (success)
612 {
613 m_numStats = numResults;
614 m_stats = results;
615 ret = RetrieveStats();
616 }
617 else ret = true;
618
619 //else LeaderboardManager::Instance()->SetStatsRetrieved(false);
620
621 PopulateLeaderboard(!success);
622
623 m_isProcessingStatsRead = false;
624
625 return ret;
626}
627
628
629bool CScene_Leaderboards::RetrieveStats()
630{
631
632 if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards)))
633 {
634 m_leaderboard.m_totalEntryCount = NUM_ENTRIES;
635 m_leaderboard.m_currentEntryCount = NUM_ENTRIES;
636 m_leaderboard.m_entryStartIndex = 1;
637 m_leaderboard.m_numColumns = LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount;
638
639 //For each entry in the leaderboard
640 for( unsigned int entryIndex=0 ; entryIndex<m_leaderboard.m_currentEntryCount ; entryIndex++ )
641 {
642 m_leaderboard.m_entries[entryIndex].m_xuid = INVALID_XUID;
643
644 m_leaderboard.m_entries[entryIndex].m_rank = entryIndex+1;
645 swprintf(m_leaderboard.m_entries[entryIndex].m_wcRank, 12, L"12345678");//(int)m_leaderboard.m_entries[entryIndex].m_rank);
646
647 swprintf(m_leaderboard.m_entries[entryIndex].m_gamerTag, 17, L"WWWWWWWWWWWWWWWW");
648
649 //m_leaderboard.m_entries[entryIndex].m_locale = (entryIndex % 37) + 1;
650
651 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;
652
653 for( unsigned int i=0 ; i<m_leaderboard.m_numColumns ; i++ )
654 {
655 if( !isDistanceLeaderboard )
656 {
657 m_leaderboard.m_entries[entryIndex].m_columns[i] = USHRT_MAX;
658 swprintf(m_leaderboard.m_entries[entryIndex].m_wcColumns[i], 12, L"%u", m_leaderboard.m_entries[entryIndex].m_columns[i]);
659 }
660 else
661 {
662 m_leaderboard.m_entries[entryIndex].m_columns[i] = UINT_MAX;
663 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);
664 }
665 }
666
667 m_leaderboard.m_entries[entryIndex].m_bPlayer = (entryIndex == 0);
668 m_leaderboard.m_entries[entryIndex].m_bOnline = (entryIndex != 0);
669 m_leaderboard.m_entries[entryIndex].m_bFriend = (entryIndex != 0);
670 m_leaderboard.m_entries[entryIndex].m_bRequestedFriend = false;
671 }
672
673 //LeaderboardManager::Instance()->SetStatsRetrieved(true);
674
675 return true;
676 }
677
678 //assert( LeaderboardManager::Instance()->GetStats() != NULL );
679 //PXUSER_STATS_READ_RESULTS stats = LeaderboardManager::Instance()->GetStats();
680 //if( m_currentFilter == LeaderboardManager::eFM_Friends ) LeaderboardManager::Instance()->SortFriendStats();
681
682 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;
683
684 //First read
685 if( m_leaderboard.m_totalEntryCount == 0 )
686 {
687 m_leaderboard.m_totalEntryCount = (m_currentFilter == LeaderboardManager::eFM_Friends) ? m_stats->pViews[0].dwNumRows : m_stats->pViews[0].dwTotalViewRows;
688 m_leaderboard.m_currentEntryCount = m_stats->pViews[0].dwNumRows;
689
690 if( m_leaderboard.m_totalEntryCount == 0 || m_leaderboard.m_currentEntryCount == 0 )
691 {
692 //LeaderboardManager::Instance()->SetStatsRetrieved(false);
693 return false;
694 }
695
696 m_leaderboard.m_numColumns = m_stats->pViews[0].pRows[0].dwNumColumns;
697
698 m_leaderboard.m_entryStartIndex = (m_currentFilter == LeaderboardManager::eFM_Friends) ? 1 : m_stats->pViews[0].pRows[0].dwRank;
699
700 for( unsigned int entryIndex=0 ; entryIndex<m_leaderboard.m_currentEntryCount ; ++entryIndex )
701 CopyLeaderboardEntry(&(m_stats->pViews[0].pRows[entryIndex]), &(m_leaderboard.m_entries[entryIndex]), isDistanceLeaderboard);
702
703 //If the filter mode is "My Score" then centre the list around the entries and select the player's score
704 if( m_currentFilter == LeaderboardManager::eFM_MyScore )
705 {
706 //Centre the leaderboard list on the entries
707 m_newTop = m_leaderboard.m_entryStartIndex-1;
708
709 //Select the player entry
710 for( unsigned int i=m_leaderboard.m_entryStartIndex ; i<m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount ; ++i )
711 if( m_leaderboard.m_entries[i-m_leaderboard.m_entryStartIndex].m_bPlayer )
712 {
713 m_newSel = i-1; // this might be off the screen!
714 // and reposition the top one
715 if(m_newSel-m_newTop>9)
716 {
717 m_newTop=m_newSel-9;
718 }
719 break;
720 }
721 }
722 }
723 //Additional read
724 else
725 {
726 unsigned int insertPosition = 0;
727
728 //If the first new entry is at a smaller index than the current first entry
729 if( m_newEntryIndex < m_leaderboard.m_entryStartIndex )
730 {
731 if( (m_leaderboard.m_entryStartIndex-1) < m_newReadSize )
732 m_newReadSize = m_leaderboard.m_entryStartIndex-1;
733
734 //Move current entries forward
735 memmove((void*)(m_leaderboard.m_entries+m_newReadSize), (void*)m_leaderboard.m_entries, sizeof(LeaderboardEntry)*(NUM_ENTRIES-m_newReadSize));
736
737 //Set the (now smaller) entry start index
738 m_leaderboard.m_entryStartIndex = m_newEntryIndex;
739
740 //We will be inserting the new entries at the start of the array
741 insertPosition = 0;
742
743 //Entry count is either max possible entries or current entry count + read size, whichever is smaller
744 m_leaderboard.m_currentEntryCount = min((int)NUM_ENTRIES, (int)(m_leaderboard.m_currentEntryCount+m_newReadSize));
745 }
746 //If the last new entry is at a greater position than the last possible entry
747 else if( m_newEntryIndex+m_newReadSize-1 >= m_leaderboard.m_entryStartIndex+NUM_ENTRIES )
748 {
749 //Calculate the overlap (this is by how much new entries would overhang the end of the array)
750 int overlap = (((m_newEntryIndex-1)+m_newReadSize-1) - (m_leaderboard.m_entryStartIndex-1)) - NUM_ENTRIES + 1;
751
752 //Move current entries backwards
753 memmove((void*)m_leaderboard.m_entries, (void*)(m_leaderboard.m_entries+overlap), sizeof(LeaderboardEntry)*(NUM_ENTRIES-overlap));
754
755 //Set the (now larger) start index
756 m_leaderboard.m_entryStartIndex += overlap;
757
758 //We will be inserting the new entries at the end of the array
759 insertPosition = NUM_ENTRIES - m_newReadSize;
760
761 //Entry count is max possible entries
762 m_leaderboard.m_currentEntryCount = NUM_ENTRIES;
763 }
764 //Otherwise we're inserting at the end of the array and there is plenty of room
765 else
766 {
767 insertPosition = m_leaderboard.m_currentEntryCount;
768 m_leaderboard.m_currentEntryCount += m_newReadSize;
769 }
770
771 //For each entry in the leaderboard
772 for( unsigned int entryIndex=0 ; entryIndex<m_newReadSize ; ++entryIndex )
773 {
774 CopyLeaderboardEntry(&(m_stats->pViews[0].pRows[entryIndex]), &(m_leaderboard.m_entries[insertPosition]), isDistanceLeaderboard);
775 insertPosition++;
776 }
777 }
778
779 //LeaderboardManager::Instance()->SetStatsRetrieved(true);
780 return true;
781}
782
783HRESULT CScene_Leaderboards::OnGetItemCountAll(XUIMessageGetItemCount *pGetItemCountData, BOOL& bHandled)
784{
785 pGetItemCountData->cItems = m_leaderboard.m_totalEntryCount;
786
787 //if(LeaderboardManager::Instance()->GetStatsRead())
788 //{
789 // m_bReady=true;
790 //}
791 bHandled = TRUE;
792
793 return S_OK;
794}
795
796HRESULT CScene_Leaderboards::OnGetSourceDataText(XUIMessageGetSourceText *pGetSourceTextData,BOOL& bHandled)
797{
798 if( pGetSourceTextData->bItemData )
799 {
800 if( m_newTop != -1 && m_newSel != -1 )
801 {
802 HRESULT ret = m_listGamers.SetTopItem(m_newTop);
803 assert( ret == S_OK );
804
805 ret = m_listGamers.SetCurSel(m_newSel);
806 assert( ret == S_OK );
807
808 // update the tooltips
809
810 m_newTop = m_newSel = -1;
811
812 bHandled = true;
813 return S_OK;
814 }
815
816 unsigned int item = pGetSourceTextData->iItem;
817
818 if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < m_leaderboard.m_entryStartIndex )
819 {
820 if( LeaderboardManager::Instance()->isIdle() )
821 {
822 int readIndex = m_leaderboard.m_entryStartIndex - READ_SIZE;
823 if( readIndex <= 0 )
824 readIndex = 1;
825 assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount );
826 ReadStats(readIndex);
827 }
828 }
829 else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount) )
830 {
831 if( LeaderboardManager::Instance()->isIdle() )
832 {
833 int readIndex = m_leaderboard.m_entryStartIndex + m_leaderboard.m_currentEntryCount;
834 assert( readIndex >= 1 && readIndex <= (int)m_leaderboard.m_totalEntryCount );
835 ReadStats(readIndex);
836 }
837 }
838 else
839 {
840 unsigned int index = item - (m_leaderboard.m_entryStartIndex-1);
841 if( 0 == pGetSourceTextData->iData )
842 {
843 pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_wcRank;
844 bHandled = TRUE;
845 }
846 else if( 1 == pGetSourceTextData->iData )
847 {
848 pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_gamerTag;
849 bHandled = TRUE;
850 }
851 else if( pGetSourceTextData->iData >= 3 && pGetSourceTextData->iData <= 9 )
852 {
853 if( m_leaderboard.m_numColumns <= (unsigned int)(pGetSourceTextData->iData-3) )
854 pGetSourceTextData->szText = L"";
855 else
856 pGetSourceTextData->szText = m_leaderboard.m_entries[index].m_wcColumns[pGetSourceTextData->iData-3];
857 bHandled = TRUE;
858 }
859 }
860 }
861 return S_OK;
862}
863
864HRESULT CScene_Leaderboards::OnGetSourceDataImage(XUIMessageGetSourceImage* pGetImage, BOOL& bHandled)
865{
866 if( (pGetImage->iData == 2) && (pGetImage->bItemData) )
867 {
868 if( m_newTop != -1 && m_newSel != -1 )
869 {
870 //Do nothing, alignment handled in OnGetSourceDataText
871
872 bHandled = true;
873 return S_OK;
874 }
875
876 unsigned int item = pGetImage->iItem;
877 if( m_leaderboard.m_totalEntryCount > 0 && (item+1) < m_leaderboard.m_entryStartIndex )
878 {
879 //Do nothing, reading handled in OnGetSourceDataText
880 }
881 else if( m_leaderboard.m_totalEntryCount > 0 && (item+1) >= (m_leaderboard.m_entryStartIndex+m_leaderboard.m_currentEntryCount) )
882 {
883 //Do nothing, reading handled in OnGetSourceDataText
884 }
885 // 4J-PB - we're not allowed to show flags any more
886// else
887// {
888// unsigned int index = item - (m_leaderboard.m_entryStartIndex-1);
889// if( m_leaderboard.m_entries[index].m_locale > 0 && m_leaderboard.m_entries[index].m_locale <= XC_LOCALE_RUSSIAN_FEDERATION )
890// pGetImage->szPath = FLAG_ICON_PATHS[ m_leaderboard.m_entries[index].m_locale-1 ];
891// bHandled = TRUE;
892// }
893 }
894
895 return S_OK;
896}
897
898void CScene_Leaderboards::PopulateLeaderboard(bool noResults)
899{
900 HRESULT hr;
901 HXUIOBJ visual=NULL;
902 HXUIOBJ hTemp=NULL;
903 hr=XuiControlGetVisual(m_listGamers.m_hObj,&visual);
904
905 if(m_pHTitleIconSlots[0]==NULL)
906 {
907 VOID *pObj;
908 HXUIOBJ button;
909 D3DXVECTOR3 vPos;
910
911 for(int i=0;i<7;i++)
912 {
913 // retrieve the visual for the title icon
914 hr=XuiElementGetChildById(visual,m_TitleIconNameA[i],&button);
915
916 XuiObjectFromHandle( button, &pObj );
917 m_pHTitleIconSlots[i] = (CXuiCtrlCraftIngredientSlot *)pObj;
918
919 // store the default position, since we'll be repositioning these depending on how many are valid for each board
920 m_pHTitleIconSlots[i]->GetPosition(&vPos);
921 m_fTitleIconXPositions[i]= vPos.x;
922 }
923 }
924
925 int iValidSlots=SetLeaderboardTitleIcons();
926
927 if( !noResults && m_leaderboard.m_totalEntryCount > 0 )
928 {
929 hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp);
930 if(hTemp)
931 {
932 XuiControlSetText(hTemp,app.GetString( IDS_LEADERBOARD_GAMERTAG ));
933 XuiElementSetShow(hTemp, TRUE);
934 }
935 hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp);
936 if(hTemp)
937 {
938 XuiControlSetText(hTemp,app.GetString( IDS_LEADERBOARD_RANK ));
939 XuiElementSetShow(hTemp, TRUE);
940 }
941
942 //Update entries display
943 wchar_t entriesBuffer[40];
944 if(app.DebugSettingsOn() && (app.GetGameSettingsDebugMask()&(1L<<eDebugSetting_DebugLeaderboards)))
945 {
946 swprintf(entriesBuffer, 40, L"%ls12345678", app.GetString(IDS_LEADERBOARD_ENTRIES));
947 }
948 else
949 {
950 swprintf(entriesBuffer, 40, L"%ls%i", app.GetString(IDS_LEADERBOARD_ENTRIES), m_leaderboard.m_totalEntryCount);
951 }
952
953 m_textEntries.SetText(entriesBuffer);
954
955 //Hide the loading message
956 m_textInfo.SetShow(false);
957
958 //Add space for new entries
959 m_listGamers.InsertItems(0, m_leaderboard.m_totalEntryCount);
960
961 // 4J Stu - Fix for leaderboards taking forever to update. Was looping over m_totalEntryCount which is ~2mil in
962 // some leaderboards in production atm.
963 // Changed to loop over the range of cached values, although even that is probably overkill.
964 // Really only the newly updated rows need changed, but this shouldn't cause any performance issues
965 for(DWORD i = m_leaderboard.m_entryStartIndex - 1; i < (m_leaderboard.m_entryStartIndex - 1) + m_leaderboard.m_currentEntryCount; ++i)
966 {
967 HXUIOBJ visual=NULL;
968 HXUIOBJ button;
969 D3DXVECTOR3 vPos;
970 // 4J-PB - fix for #13768 - Leaderboards: Player scores appear misaligned when viewed under the "My Score" leaderboard filter
971 HXUIOBJ hTop=m_listGamers.GetItemControl(i-(m_leaderboard.m_entryStartIndex - 1));
972 HRESULT hr=XuiControlGetVisual(hTop,&visual);
973
974 for(int j=0;j<7;j++)
975 {
976 hr=XuiElementGetChildById(visual,m_TextColumnNameA[j],&button);
977 m_hTextEntryA[j]=button;
978
979 XuiElementGetPosition(button,&vPos);
980 m_fTextXPositions[j]=vPos.x;
981 }
982 RepositionText(iValidSlots);
983 }
984
985 // hide empty icon boxes
986 for(int i = (LEADERBOARD_DESCRIPTORS[m_currentLeaderboard][m_currentDifficulty].m_columnCount);i<7;i++)
987 {
988 m_pHTitleIconSlots[i]->SetShow(FALSE);
989 }
990 }
991 else
992 {
993 hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp);
994 if(hTemp)
995 {
996 XuiElementSetShow(hTemp, FALSE);
997 }
998 hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp);
999 if(hTemp)
1000 {
1001 XuiElementSetShow(hTemp, FALSE);
1002 }
1003
1004 //Update entries display (to zero)
1005 wchar_t entriesBuffer[40];
1006 swprintf(entriesBuffer, 40, L"%ls0", app.GetString(IDS_LEADERBOARD_ENTRIES));
1007 m_textEntries.SetText(entriesBuffer);
1008
1009 //Show the no results message
1010 m_textInfo.SetText(app.GetString(IDS_LEADERBOARD_NORESULTS));
1011 m_textInfo.SetShow(true);
1012
1013 // hide the icons
1014 for(int i=0;i<7;i++)
1015 {
1016 m_pHTitleIconSlots[i]->SetShow(FALSE);
1017 }
1018
1019 }
1020
1021 m_bPopulatedOnce = true;
1022}
1023
1024void CScene_Leaderboards::CopyLeaderboardEntry(PXUSER_STATS_ROW statsRow, LeaderboardEntry* leaderboardEntry, bool isDistanceLeaderboard)
1025{
1026 leaderboardEntry->m_xuid = statsRow->xuid;
1027
1028 //Copy the rank
1029 leaderboardEntry->m_rank = statsRow->dwRank;
1030 DWORD displayRank = leaderboardEntry->m_rank;
1031 if(displayRank > 9999999) displayRank = 9999999;
1032 swprintf_s(leaderboardEntry->m_wcRank, 12, L"%u", displayRank);
1033
1034 //strcpy(statsRow->szGamertag,"WWWWWWWWWWWWWWWW");
1035
1036 //Convert the gamertag from char to wchar_t
1037 MultiByteToWideChar(
1038 CP_UTF8,
1039 0,
1040 statsRow->szGamertag,
1041 strlen(statsRow->szGamertag),
1042 leaderboardEntry->m_gamerTag,
1043 XUSER_NAME_SIZE );
1044 //Null terminate the gamertag
1045 leaderboardEntry->m_gamerTag[strlen(statsRow->szGamertag)] = L'\0';
1046
1047 //Copy the locale
1048 //leaderboardEntry->m_locale = statsRow->pColumns[0].Value.nData;
1049
1050 //Copy the other columns
1051 for( unsigned int i=0 ; i<statsRow->dwNumColumns ; i++ )
1052 {
1053 leaderboardEntry->m_columns[i] = statsRow->pColumns[i].Value.nData;
1054 if( !isDistanceLeaderboard )
1055 {
1056 DWORD displayValue = leaderboardEntry->m_columns[i];
1057 if(displayValue > 99999) displayValue = 99999;
1058 swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%u",displayValue);
1059#ifdef _DEBUG
1060 app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]);
1061#endif
1062 }
1063 else
1064 {
1065 // check how many digits we have
1066 int iDigitC=0;
1067 unsigned int uiVal=leaderboardEntry->m_columns[i];
1068// uiVal=0xFFFFFFFF;
1069// leaderboardEntry->m_columns[i-1]=uiVal;
1070
1071 while(uiVal!=0)
1072 {
1073 uiVal/=10;
1074 iDigitC++;
1075 }
1076
1077#ifdef _DEBUG
1078 app.DebugPrintf("Value - %d\n",leaderboardEntry->m_columns[i]);
1079#endif
1080 if(iDigitC<4)
1081 {
1082 // m
1083 swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%um", leaderboardEntry->m_columns[i]);
1084#ifdef _DEBUG
1085 app.DebugPrintf("Display - %um\n", leaderboardEntry->m_columns[i]);
1086#endif
1087 }
1088 else if(iDigitC<8)
1089 {
1090 // km with a .X
1091 swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%.1fkm", ((float)leaderboardEntry->m_columns[i])/1000.f);
1092#ifdef _DEBUG
1093 app.DebugPrintf("Display - %.1fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f);
1094#endif
1095 }
1096 else
1097 {
1098 // bigger than that, so no decimal point
1099 swprintf_s(leaderboardEntry->m_wcColumns[i], 12, L"%.0fkm", ((float)leaderboardEntry->m_columns[i])/1000.f);
1100#ifdef _DEBUG
1101 app.DebugPrintf("Display - %.0fkm\n", ((float)leaderboardEntry->m_columns[i])/1000.f);
1102#endif
1103 }
1104 }
1105 }
1106
1107 //Is the player
1108 if( statsRow->xuid == ((XboxLeaderboardManager*)LeaderboardManager::Instance())->GetMyXUID() )
1109 {
1110 leaderboardEntry->m_bPlayer = true;
1111 leaderboardEntry->m_bOnline = false;
1112 leaderboardEntry->m_bFriend = false;
1113 leaderboardEntry->m_bRequestedFriend = false;
1114 }
1115 else
1116 {
1117 leaderboardEntry->m_bPlayer = false;
1118 leaderboardEntry->m_bOnline = false;
1119 leaderboardEntry->m_bFriend = false;
1120 leaderboardEntry->m_bRequestedFriend = false;
1121
1122 //Check for friend status
1123 for( unsigned int friendIndex=0 ; friendIndex<m_numFriends ; ++friendIndex )
1124 {
1125 if( m_friends[friendIndex].xuid == statsRow->xuid )
1126 {
1127 if( ( m_friends[friendIndex].dwFriendState & ( XONLINE_FRIENDSTATE_FLAG_SENTREQUEST | XONLINE_FRIENDSTATE_FLAG_RECEIVEDREQUEST ) ) == 0 )
1128 {
1129 //Is friend, might be online
1130 leaderboardEntry->m_bFriend = true;
1131 leaderboardEntry->m_bOnline = ( m_friends[friendIndex].dwFriendState & XONLINE_FRIENDSTATE_FLAG_ONLINE );
1132 leaderboardEntry->m_bRequestedFriend = false;
1133 }
1134 else
1135 {
1136 //Friend request sent but not accepted yet
1137 leaderboardEntry->m_bOnline = false;
1138 leaderboardEntry->m_bFriend = false;
1139 leaderboardEntry->m_bRequestedFriend = true;
1140 }
1141
1142 break;
1143 }
1144 }
1145 }
1146}
1147
1148void CScene_Leaderboards::SetLeaderboardHeader()
1149{
1150 WCHAR buffer[40];
1151 DWORD bufferLength = 40;
1152
1153 DWORD ret = XResourceGetString(LEADERBOARD_HEADERS[m_currentLeaderboard][m_currentDifficulty], buffer, &bufferLength, NULL);
1154
1155 if( ret == ERROR_SUCCESS )
1156 m_textLeaderboard.SetText(buffer);
1157}
1158
1159int CScene_Leaderboards::SetLeaderboardTitleIcons()
1160{
1161 int iValidIcons=0;
1162
1163 for(int i=0;i<7;i++)
1164 {
1165 if(TitleIcons[m_currentLeaderboard][i]==0)
1166 {
1167 m_pHTitleIconSlots[i]->SetShow(FALSE);
1168 }
1169 else
1170 {
1171 iValidIcons++;
1172 m_pHTitleIconSlots[i]->SetIcon(DEFAULT_XUI_MENU_USER,TitleIcons[m_currentLeaderboard][i],0,1,10,31,false,FALSE);
1173 }
1174 }
1175
1176 Reposition(iValidIcons);
1177
1178 return iValidIcons;
1179}
1180void CScene_Leaderboards::ClearLeaderboardTitlebar()
1181{
1182 for(int i=0;i<7;i++)
1183 {
1184 m_pHTitleIconSlots[i]->SetShow(FALSE);
1185 }
1186
1187 HXUIOBJ visual=NULL;
1188 HXUIOBJ hTemp=NULL;
1189 HRESULT hr;
1190 hr=XuiControlGetVisual(m_listGamers.m_hObj,&visual);
1191
1192 hr=XuiElementGetChildById(visual,L"XuiLabel_Gamertag",&hTemp);
1193 if(hTemp)
1194 {
1195 XuiElementSetShow(hTemp, FALSE);
1196 }
1197 hr=XuiElementGetChildById(visual,L"XuiLabel_Rank",&hTemp);
1198 if(hTemp)
1199 {
1200 XuiElementSetShow(hTemp, FALSE);
1201 }
1202}