the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 2767 lines 83 kB view raw
1#include "stdafx.h" 2#include <xuiresource.h> 3#include <xuiapp.h> 4#include <assert.h> 5#include "..\..\..\Minecraft.World\StringHelpers.h" 6#include "..\..\Common\Tutorial\TutorialMode.h" 7#include "..\..\..\Minecraft.World\ConsoleSaveFileIO.h" 8#include "..\..\LocalPlayer.h" 9#include "..\..\Minecraft.h" 10#include "..\..\ProgressRenderer.h" 11#include "..\..\..\Minecraft.World\AABB.h" 12#include "..\..\..\Minecraft.World\Vec3.h" 13#include "..\..\..\Minecraft.World\ArrayWithLength.h" 14#include "..\..\..\Minecraft.World\File.h" 15#include "..\..\..\Minecraft.World\InputOutputStream.h" 16#include "XUI_Ctrl_4JList.h" 17#include "XUI_Ctrl_4JIcon.h" 18#include "XUI_LoadSettings.h" 19#include "XUI_MultiGameInfo.h" 20#include "XUI_MultiGameJoinLoad.h" 21#include "XUI_MultiGameCreate.h" 22#include "..\..\MinecraftServer.h" 23#include "..\..\Options.h" 24 25#include "..\GameRules\LevelGenerationOptions.h" 26#include "..\..\TexturePackRepository.h" 27#include "..\..\TexturePack.h" 28#include "..\..\..\Minecraft.World\LevelSettings.h" 29 30#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID 3 31#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 100 32 33//---------------------------------------------------------------------------------- 34// Performs initialization tasks - retrieves controls. 35//---------------------------------------------------------------------------------- 36HRESULT CScene_MultiGameJoinLoad::OnInit( XUIMessageInit* pInitData, BOOL& bHandled ) 37{ 38 39 m_iPad=*(int *)pInitData->pvInitData; 40 m_bReady=false; 41 MapChildControls(); 42 43 m_iTexturePacksNotInstalled=0; 44 m_iConfigA=NULL; 45 46 XuiControlSetText(m_LabelNoGames,app.GetString(IDS_NO_GAMES_FOUND)); 47 XuiControlSetText(m_GamesList,app.GetString(IDS_JOIN_GAME)); 48 XuiControlSetText(m_SavesList,app.GetString(IDS_START_GAME)); 49 50 51 const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string 52 WCHAR szResourceLocator[ LOCATOR_SIZE ]; 53 54 const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(NULL); 55 swprintf(szResourceLocator, LOCATOR_SIZE ,L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/Graphics/TexturePackIcon.png"); 56 57 m_DefaultMinecraftIconSize = 0; 58 HRESULT hr = XuiResourceLoadAllNoLoc(szResourceLocator, &m_DefaultMinecraftIconData, &m_DefaultMinecraftIconSize); 59 60 m_localPlayers = 1; 61 m_bKillSaveInfoEnumerate=false; 62 63 m_bShowingPartyGamesOnly = false; 64 65 m_bRetrievingSaveInfo=false; 66 m_bSaveTransferInProgress=false; 67 68 // check for a default custom cloak in the global storage 69 // 4J-PB - changed to a config file 70// if(ProfileManager.IsSignedInLive( m_iPad )) 71// { 72// app.InstallDefaultCape(); 73// } 74 75 m_initData= new JoinMenuInitData(); 76 m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); 77 78 XPARTY_USER_LIST partyList; 79 80 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1)) 81 { 82 m_bInParty=true; 83 } 84 else 85 { 86 m_bInParty=false; 87 } 88 89 int iLB = -1; 90 if(m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES; 91 92 XuiSetTimer(m_hObj,JOIN_LOAD_ONLINE_TIMER_ID,JOIN_LOAD_ONLINE_TIMER_TIME); 93 94 m_iSaveInfoC=0; 95 96 VOID *pObj; 97 XuiObjectFromHandle( m_SavesList, &pObj ); 98 m_pSavesList = (CXuiCtrl4JList *)pObj; 99 100 XuiObjectFromHandle( m_GamesList, &pObj ); 101 m_pGamesList = (CXuiCtrl4JList *)pObj; 102 103 // block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again 104 if(app.StartInstallDLCProcess(m_iPad)==true) 105 { 106 // not doing a mount, so enable input 107 m_bIgnoreInput=true; 108 } 109 else 110 { 111 // if we're waiting for DLC to mount, don't fill the save list. The custom message on end of dlc mounting will do that 112 m_bIgnoreInput=false; 113 114 115 116 m_iChangingSaveGameInfoIndex = 0; 117 118 m_generators = app.getLevelGenerators(); 119 m_iDefaultButtonsC = 0; 120 m_iMashUpButtonsC=0; 121 122 // check if we're in the trial version 123 if(ProfileManager.IsFullVersion()==false) 124 { 125 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK, -1, -1, -1, -1,iLB); 126 127 AddDefaultButtons(); 128 129 m_pSavesList->SetCurSelVisible(0); 130 } 131 else if(StorageManager.GetSaveDisabled()) 132 { 133 if(StorageManager.GetSaveDeviceSelected(m_iPad)) 134 { 135 // saving is disabled, but we should still be able to load from a selected save device 136 137 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,-1,-1,-1,iLB,IDS_TOOLTIPS_DELETESAVE); 138 139 GetSaveInfo(); 140 } 141 else 142 { 143 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,-1,-1,-1,iLB); 144 145 AddDefaultButtons(); 146 m_SavesListTimer.SetShow( FALSE ); 147 148 m_pSavesList->SetCurSelVisible(0); 149 } 150 } 151 else 152 { 153 // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename) 154 bool bCanRename = StorageManager.EnoughSpaceForAMinSaveGame(); 155 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,-1,-1,-1,-1,bCanRename?IDS_TOOLTIPS_SAVEOPTIONS:IDS_TOOLTIPS_DELETESAVE); 156 157 GetSaveInfo(); 158 } 159 } 160 //XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, TRUE); 161 162 UpdateGamesList(); 163 164 g_NetworkManager.SetSessionsUpdatedCallback( &CScene_MultiGameJoinLoad::UpdateGamesListCallback, this ); 165 166 // 4J Stu - Fix for #12530 -TCR 001 BAS Game Stability: Title will crash if the player disconnects while starting a new world and then opts to play the tutorial once they have been returned to the Main Menu. 167 MinecraftServer::resetFlags(); 168 169 // If we're not ignoring input, then we aren't still waiting for the DLC to mount, and can now check for corrupt dlc. Otherwise this will happen when the dlc has finished mounting. 170 if( !m_bIgnoreInput) 171 { 172 app.m_dlcManager.checkForCorruptDLCAndAlert(); 173 } 174 175 176 // 4J-PB - Load up any texture pack data we have locally in the XZP 177 for(int i=0;i<TMS_COUNT;i++) 178 { 179 if(app.TMSFileA[i].eTMSType==eTMSFileType_TexturePack) 180 { 181 app.LoadLocalTMSFile(app.TMSFileA[i].wchFilename,app.TMSFileA[i].eEXT); 182 app.AddMemoryTPDFile(app.TMSFileA[i].iConfig, app.TMSFileA[i].pbData,app.TMSFileA[i].uiSize); 183 } 184 } 185 186 // 4J-PB - there may be texture packs we don't have, so use the info from TMS for this 187 188 DLC_INFO *pDLCInfo=NULL; 189 190 // first pass - look to see if there are any that are not in the list 191 bool bTexturePackAlreadyListed; 192 bool bNeedToGetTPD=false; 193 Minecraft *pMinecraft = Minecraft::GetInstance(); 194 int texturePacksCount = pMinecraft->skins->getTexturePackCount(); 195 //CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 196 //HRESULT hr; 197 198 199 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) 200 { 201 bTexturePackAlreadyListed=false; 202 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); 203 pDLCInfo=app.GetDLCInfoForFullOfferID(ull); 204 for(unsigned int i = 0; i < texturePacksCount; ++i) 205 { 206 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i); 207 if(pDLCInfo->iConfig==tp->getDLCParentPackId()) 208 { 209 bTexturePackAlreadyListed=true; 210 } 211 } 212 if(bTexturePackAlreadyListed==false) 213 { 214 // some missing 215 bNeedToGetTPD=true; 216 217 m_iTexturePacksNotInstalled++; 218 } 219 } 220 221 if(bNeedToGetTPD==true) 222 { 223 // add a TMS request for them 224 app.DebugPrintf("+++ Adding TMSPP request for texture pack data\n"); 225 app.AddTMSPPFileTypeRequest(e_DLC_TexturePackData); 226 m_iConfigA= new int [m_iTexturePacksNotInstalled]; 227 m_iTexturePacksNotInstalled=0; 228 229 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) 230 { 231 bTexturePackAlreadyListed=false; 232 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i); 233 pDLCInfo=app.GetDLCInfoForFullOfferID(ull); 234 for(unsigned int i = 0; i < texturePacksCount; ++i) 235 { 236 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i); 237 if(pDLCInfo->iConfig==tp->getDLCParentPackId()) 238 { 239 bTexturePackAlreadyListed=true; 240 } 241 } 242 if(bTexturePackAlreadyListed==false) 243 { 244 m_iConfigA[m_iTexturePacksNotInstalled++]=pDLCInfo->iConfig; 245 } 246 } 247 } 248 249 XuiSetTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME); 250 251 return S_OK; 252} 253 254void CScene_MultiGameJoinLoad::AddDefaultButtons() 255{ 256 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 257 258 // Add two for New Game and Tutorial 259 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); 260 261 ListInfo.pwszText = app.GetString(IDS_CREATE_NEW_WORLD); 262 ListInfo.fEnabled = TRUE; 263 ListInfo.iData = -1; 264 m_pSavesList->AddData(ListInfo); 265 266 int iSavesListIndex = 0; 267 int iGeneratorIndex = 0; 268 m_iMashUpButtonsC=0; 269 270 for(AUTO_VAR(it, m_generators->begin()); it != m_generators->end(); ++it) 271 { 272 LevelGenerationOptions *levelGen = *it; 273 ListInfo.pwszText = levelGen->getWorldName(); 274 ListInfo.fEnabled = TRUE; 275 ListInfo.iData = iGeneratorIndex++; // used to index into the list of generators 276 277 // need to check if the user has disabled this pack in the save display list 278 unsigned int uiTexturePackID=levelGen->getRequiredTexturePackId(); 279 280 if(uiTexturePackID!=0) 281 { 282 unsigned int uiMashUpWorldsBitmask=app.GetMashupPackWorlds(m_iPad); 283 284 if((uiMashUpWorldsBitmask & (1<<(uiTexturePackID-1024)))==0) 285 { 286 // this world is hidden, so skip 287 continue; 288 } 289 } 290 m_pSavesList->AddData(ListInfo); 291 292 // retrieve the save icon from the texture pack, if there is one 293 if(uiTexturePackID!=0) 294 { 295 // increment the count of the mash-up pack worlds in the save list 296 m_iMashUpButtonsC++; 297 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackById(levelGen->getRequiredTexturePackId()); 298 DWORD dwImageBytes; 299 PBYTE pbImageData = tp->getPackIcon(dwImageBytes); 300 HXUIBRUSH hXuiBrush; 301 302 if(dwImageBytes > 0 && pbImageData) 303 { 304 XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&hXuiBrush); 305 // the index inside the list item for this will be i+1 because they start at m_vListData.size(), so the first etry (tutorial) is 1 306 m_pSavesList->UpdateGraphic(iSavesListIndex+1,hXuiBrush); 307 } 308 } 309 310 ++iSavesListIndex; 311 } 312 313 m_iDefaultButtonsC = iSavesListIndex + 1; 314} 315 316 317HRESULT CScene_MultiGameJoinLoad::GetSaveInfo( ) 318{ 319 unsigned int uiSaveC=0; 320 321 // This will return with the number retrieved in uiSaveC 322 323 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) 324 { 325 uiSaveC = 0; 326 File savesDir(L"GAME:\\Saves"); 327 if( savesDir.exists() ) 328 { 329 m_saves = savesDir.listFiles(); 330 uiSaveC = (unsigned int)m_saves->size(); 331 } 332 // add the New Game and Tutorial after the saves list is retrieved, if there are any saves 333 334 // Add two for New Game and Tutorial 335 unsigned int listItems = uiSaveC; 336 337 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 338 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); 339 340 AddDefaultButtons(); 341 342 for(unsigned int i=0;i<listItems;i++) 343 { 344 345 wstring wName = m_saves->at(i)->getName(); 346 wchar_t *name = new wchar_t[wName.size()+1]; 347 for(unsigned int j = 0; j < wName.size(); ++j) 348 { 349 name[j] = wName[j]; 350 } 351 name[wName.size()] = 0; 352 ListInfo.pwszText = name; 353 ListInfo.fEnabled=TRUE; 354 ListInfo.iData = -1; 355 m_pSavesList->AddData(ListInfo); 356 } 357 m_pSavesList->SetCurSelVisible(0); 358 } 359 else 360 { 361 m_bRetrievingSaveInfo=true; // we're blocking the exit from this scene until complete 362 363 // clear the saves list 364 m_pSavesList->RemoveAllData(); 365 366 m_iSaveInfoC=0; 367#ifdef _XBOX 368 C4JStorage::ESGIStatus eSGIStatus=StorageManager.GetSavesInfo(ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::GetSavesInfoCallback,this,"savegame.dat"); 369 370 if(eSGIStatus==C4JStorage::ESGIStatus_NoSaves) 371 { 372 uiSaveC=0; 373 m_SavesListTimer.SetShow( FALSE ); 374 m_SavesList.SetEnable(TRUE); 375 } 376#else 377 378 //C4JStorage::ESaveGameState eStatus=StorageManager.GetSavesInfo(ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::GetSavesInfoCallback,this,"savegame.dat"); 379 380#endif 381 } 382 383 return S_OK; 384} 385 386HRESULT CScene_MultiGameJoinLoad::OnDestroy() 387{ 388 g_NetworkManager.SetSessionsUpdatedCallback( NULL, NULL ); 389 390 for(AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end(); ++it) 391 { 392 delete (*it); 393 } 394 395 if(m_bSaveTransferInProgress) 396 { 397 CancelSaveUploadCallback(this); 398 } 399 400 // Reset the background downloading, in case we changed it by attempting to download a texture pack 401 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO); 402 403 // clear out the texture pack data 404 for(int i=0;i<TMS_COUNT;i++) 405 { 406 if(app.TMSFileA[i].eTMSType==eTMSFileType_TexturePack) 407 { 408 app.RemoveMemoryTPDFile(app.TMSFileA[i].iConfig); 409 } 410 } 411 app.FreeLocalTMSFiles(eTMSFileType_TexturePack); 412 413 return S_OK; 414} 415 416 417int CScene_MultiGameJoinLoad::DeviceRemovedDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 418{ 419 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 420 421 // results switched for this dialog 422 if(result==C4JStorage::EMessage_ResultDecline) 423 { 424 StorageManager.SetSaveDisabled(true); 425 StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),false); 426 // use the device select returned function to wipe the saves list and change the tooltip 427 CScene_MultiGameJoinLoad::DeviceSelectReturned(pClass,true); 428 } 429 else // continue without saving 430 { 431 // Change device 432 StorageManager.SetSaveDevice(&CScene_MultiGameJoinLoad::DeviceSelectReturned,pClass,true); 433 } 434 435 pClass->m_bIgnoreInput=false; 436 return 0; 437} 438//---------------------------------------------------------------------------------- 439// Handler for the button press message. 440//---------------------------------------------------------------------------------- 441HRESULT CScene_MultiGameJoinLoad::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled) 442{ 443 if(m_bIgnoreInput) return S_OK; 444 445 // if we're retrieving save info, ignore key presses 446 if(m_bRetrievingSaveInfo) 447 { 448 return S_OK; 449 } 450 451 // This assumes all buttons can only be pressed with the A button 452 ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A); 453 454 if ( hObjPressed == m_GamesList ) 455 { 456 m_bIgnoreInput=true; 457 458 DWORD nIndex = m_pGamesList->GetCurSel(); 459 460 if( m_pGamesList->GetItemCount() > 0 && nIndex < currentSessions.size() ) 461 { 462 //CScene_MultiGameInfo::JoinMenuInitData *initData = new CScene_MultiGameInfo::JoinMenuInitData(); 463 m_initData->iPad = m_iPad; 464 m_initData->selectedSession = currentSessions.at( nIndex ); 465 466 // check that we have the texture pack available 467 // If it's not the default texture pack 468 if(m_initData->selectedSession->data.texturePackParentId!=0) 469 { 470 int texturePacksCount = Minecraft::GetInstance()->skins->getTexturePackCount(); 471 bool bHasTexturePackInstalled=false; 472 473 for(int i=0;i<texturePacksCount;i++) 474 { 475 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackByIndex(i); 476 if(tp->getDLCParentPackId()==m_initData->selectedSession->data.texturePackParentId) 477 { 478 bHasTexturePackInstalled=true; 479 break; 480 } 481 } 482 483 if(bHasTexturePackInstalled==false) 484 { 485 // upsell the texture pack 486 // tell sentient about the upsell of the full version of the skin pack 487 ULONGLONG ullOfferID_Full; 488 app.GetDLCFullOfferIDForPackID(m_initData->selectedSession->data.texturePackParentId,&ullOfferID_Full); 489 490 TelemetryManager->RecordUpsellPresented(pNotifyPressData->UserIndex, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF); 491 492 UINT uiIDA[3]; 493 494 // Need to check if the texture pack has both Full and Trial versions - we may do some as free ones, so only Full 495 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full); 496 497 if(pDLCInfo->ullOfferID_Trial!=0LL) 498 { 499 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; 500 uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION; 501 uiIDA[2]=IDS_CONFIRM_CANCEL; 502 // Give the player a warning about the texture pack missing 503 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 3, ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::TexturePackDialogReturned,this,app.GetStringTable()); 504 } 505 else 506 { 507 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION; 508 uiIDA[1]=IDS_CONFIRM_CANCEL; 509 // Give the player a warning about the texture pack missing 510 StorageManager.RequestMessageBox(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::TexturePackDialogReturned,this,app.GetStringTable()); 511 } 512 513 return S_OK; 514 } 515 } 516 517 m_NetGamesListTimer.SetShow( FALSE ); 518 519 // Reset the background downloading, in case we changed it by attempting to download a texture pack 520 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO); 521 522 // kill the texture pack check timer 523 XuiKillTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID); 524 app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_JoinMenu,m_initData); 525 } 526 } 527 else if(hObjPressed==m_SavesList) 528 { 529 m_bIgnoreInput=true; 530 531 CXuiControl pItem; 532 int iIndex; 533 // get the selected item 534 iIndex=m_SavesList.GetCurSel(&pItem); 535 536 CXuiCtrl4JList::LIST_ITEM_INFO info = m_pSavesList->GetData(iIndex); 537 538 if(iIndex == JOIN_LOAD_CREATE_BUTTON_INDEX) 539 { 540 app.SetTutorialMode( false ); 541 m_NetGamesListTimer.SetShow( FALSE ); 542 543 app.SetCorruptSaveDeleted(false); 544 545 CreateWorldMenuInitData *params = new CreateWorldMenuInitData(); 546 params->iPad = m_iPad; 547 app.NavigateToScene(pNotifyPressData->UserIndex,eUIScene_CreateWorldMenu,(void *)params); 548 } 549 else if(info.iData >= 0) 550 { 551 LevelGenerationOptions *levelGen = m_generators->at(info.iData); 552 app.SetTutorialMode( levelGen->isTutorial() ); 553 // Reset the autosave time 554 app.SetAutosaveTimerTime(); 555 556 if(levelGen->isTutorial()) 557 { 558 LoadLevelGen(levelGen); 559 } 560 else 561 { 562 LoadMenuInitData *params = new LoadMenuInitData(); 563 params->iPad = m_iPad; 564 // need to get the iIndex from the list item, since the position in the list doesn't correspond to the GetSaveGameInfo list because of sorting 565 params->iSaveGameInfoIndex=-1; 566 //params->pbSaveRenamed=&m_bSaveRenamed; 567 params->levelGen = levelGen; 568 569 // navigate to the settings scene 570 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_LoadMenu, params); 571 } 572 } 573 else 574 { 575 // check if this is a damaged save 576 if(m_pSavesList->GetData(iIndex).bIsDamaged) 577 { 578 // give the option to delete the save 579 UINT uiIDA[2]; 580 uiIDA[0]=IDS_CONFIRM_CANCEL; 581 uiIDA[1]=IDS_CONFIRM_OK; 582 StorageManager.RequestMessageBox(IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE, IDS_CORRUPT_OR_DAMAGED_SAVE_TEXT, uiIDA, 2, pNotifyPressData->UserIndex,&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,this, app.GetStringTable()); 583 } 584 else 585 { 586 app.SetTutorialMode( false ); 587 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) 588 { 589 LoadSaveFromDisk(m_saves->at(iIndex-m_iDefaultButtonsC)); 590 } 591 else 592 { 593 LoadMenuInitData *params = new LoadMenuInitData(); 594 params->iPad = m_iPad; 595 // need to get the iIndex from the list item, since the position in the list doesn't correspond to the GetSaveGameInfo list because of sorting 596 params->iSaveGameInfoIndex=m_pSavesList->GetData(iIndex).iIndex-m_iDefaultButtonsC; 597 //params->pbSaveRenamed=&m_bSaveRenamed; 598 params->levelGen = NULL; 599 600 // kill the texture pack timer 601 XuiKillTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID); 602 // navigate to the settings scene 603 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_LoadMenu, params); 604 } 605 } 606 } 607 } 608 609 return S_OK; 610} 611 612HRESULT CScene_MultiGameJoinLoad::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) 613{ 614 if(m_bIgnoreInput) return S_OK; 615 616 // if we're retrieving save info, ignore key presses 617 if(m_bRetrievingSaveInfo) 618 { 619 return S_OK; 620 } 621 622 ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode); 623 624 HRESULT hr = S_OK; 625 626 // Explicitly handle B button presses 627 switch(pInputData->dwKeyCode) 628 { 629 case VK_PAD_B: 630 case VK_ESCAPE: 631 m_NetGamesListTimer.SetShow( FALSE ); 632 633 app.NavigateBack(XUSER_INDEX_ANY); 634 rfHandled = TRUE; 635 break; 636 case VK_PAD_X: 637 638 // Change device 639 // Fix for #12531 - TCR 001: BAS Game Stability: When a player selects to change a storage 640 // device, and repeatedly backs out of the SD screen, disconnects from LIVE, and then selects a SD, the title crashes. 641 m_bIgnoreInput=true; 642 StorageManager.SetSaveDevice(&CScene_MultiGameJoinLoad::DeviceSelectReturned,this,true); 643 CXuiSceneBase::PlayUISFX(eSFX_Press); 644 break; 645 case VK_PAD_Y: 646 if(m_pGamesList->TreeHasFocus() && m_pGamesList->GetItemCount() > 0) 647 { 648 DWORD nIndex = m_pGamesList->GetCurSel(); 649 FriendSessionInfo *pSelectedSession = currentSessions.at( nIndex ); 650 651 PlayerUID xuid = pSelectedSession->data.hostPlayerUID; 652 if( xuid != INVALID_XUID ) 653 hr = XShowGamerCardUI(ProfileManager.GetLockedProfile(), xuid); 654 CXuiSceneBase::PlayUISFX(eSFX_Press); 655 } 656 else if(DoesSavesListHaveFocus()) 657 { 658 // save transfer - make sure they want to overwrite a save that is up there 659 if(ProfileManager.IsSignedInLive( m_iPad )) 660 { 661 // 4J-PB - required for a delete of the save if it's found to be a corrupted save 662 DWORD nIndex = m_pSavesList->GetCurSel(); 663 m_iChangingSaveGameInfoIndex=m_pSavesList->GetData(nIndex).iIndex; 664 665 UINT uiIDA[2]; 666 uiIDA[0]=IDS_UPLOAD_SAVE; 667 uiIDA[1]=IDS_CONFIRM_CANCEL; 668 669 ui.RequestMessageBox(IDS_SAVE_TRANSFER_TITLE, IDS_SAVE_TRANSFER_TEXT, uiIDA, 2, pInputData->UserIndex,&CScene_MultiGameJoinLoad::SaveTransferDialogReturned,this, app.GetStringTable()); 670 } 671 } 672 break; 673 case VK_PAD_RSHOULDER: 674 if(DoesSavesListHaveFocus()) 675 { 676 m_bIgnoreInput = true; 677 678 int iIndex=m_SavesList.GetCurSel(); 679 m_iChangingSaveGameInfoIndex=m_pSavesList->GetData(iIndex).iIndex; 680 681 // Could be delete save or Save Options 682 if(StorageManager.GetSaveDisabled()) 683 { 684 // delete the save game 685 // Have to ask the player if they are sure they want to delete this game 686 UINT uiIDA[2]; 687 uiIDA[0]=IDS_CONFIRM_CANCEL; 688 uiIDA[1]=IDS_CONFIRM_OK; 689 StorageManager.RequestMessageBox(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, pInputData->UserIndex,&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,this, app.GetStringTable()); 690 } 691 else 692 { 693 if(StorageManager.EnoughSpaceForAMinSaveGame()) 694 { 695 UINT uiIDA[3]; 696 uiIDA[0]=IDS_CONFIRM_CANCEL; 697 uiIDA[1]=IDS_TITLE_RENAMESAVE; 698 uiIDA[2]=IDS_TOOLTIPS_DELETESAVE; 699 StorageManager.RequestMessageBox(IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS, uiIDA, 3, pInputData->UserIndex,&CScene_MultiGameJoinLoad::SaveOptionsDialogReturned,this, app.GetStringTable()); 700 } 701 else 702 { 703 // delete the save game 704 // Have to ask the player if they are sure they want to delete this game 705 UINT uiIDA[2]; 706 uiIDA[0]=IDS_CONFIRM_CANCEL; 707 uiIDA[1]=IDS_CONFIRM_OK; 708 StorageManager.RequestMessageBox(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, pInputData->UserIndex,&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,this, app.GetStringTable()); 709 } 710 } 711 CXuiSceneBase::PlayUISFX(eSFX_Press); 712 713 } 714 else if(DoesMashUpWorldHaveFocus()) 715 { 716 // hiding a mash-up world 717 // get the mash-up pack id 718 CXuiControl pItem; 719 int iIndex; 720 iIndex=m_SavesList.GetCurSel(&pItem); 721 722 CXuiCtrl4JList::LIST_ITEM_INFO info = m_pSavesList->GetData(iIndex); 723 if((iIndex != JOIN_LOAD_CREATE_BUTTON_INDEX) && (info.iData >= 0)) 724 { 725 LevelGenerationOptions *levelGen = m_generators->at(info.iData); 726 727 if(!levelGen->isTutorial()) 728 { 729 if(levelGen->requiresTexturePack()) 730 { 731 unsigned int uiPackID=levelGen->getRequiredTexturePackId(); 732 733 m_bIgnoreInput = true; 734 app.HideMashupPackWorld(m_iPad,uiPackID); 735 736 // update the saves list 737 m_pSavesList->RemoveAllData(); 738 m_iSaveInfoC=0; 739 GetSaveInfo(); 740 m_bIgnoreInput = false; 741 } 742 } 743 } 744 745 CXuiSceneBase::PlayUISFX(eSFX_Press); 746 747 } 748 break; 749 case VK_PAD_LSHOULDER: 750 if( m_bInParty ) 751 { 752 m_bShowingPartyGamesOnly = !m_bShowingPartyGamesOnly; 753 UpdateGamesList(); 754 CXuiSceneBase::PlayUISFX(eSFX_Press); 755 } 756 break; 757 } 758 759 return hr; 760} 761 762HRESULT CScene_MultiGameJoinLoad::OnNavReturn(HXUIOBJ hSceneFrom,BOOL& rfHandled) 763{ 764 765 CXuiSceneBase::ShowLogo( DEFAULT_XUI_MENU_USER, TRUE ); 766 // start the texture pack timer again 767 XuiSetTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME); 768 769 m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); 770 771 // re-enable button presses 772 m_bIgnoreInput=false; 773 774 if( m_bMultiplayerAllowed ) 775 { 776 HXUICLASS hClassFullscreenProgress = XuiFindClass( L"CScene_FullscreenProgress" ); 777 HXUICLASS hClassConnectingProgress = XuiFindClass( L"CScene_ConnectingProgress" ); 778 779 // If we are navigating back from a full screen progress scene, then that means a connection attempt failed 780 if( XuiIsInstanceOf( hSceneFrom, hClassFullscreenProgress ) || XuiIsInstanceOf( hSceneFrom, hClassConnectingProgress ) ) 781 { 782 UpdateGamesList(); 783 } 784 } 785 else 786 { 787 m_pGamesList->RemoveAllData(); 788 //m_GamesList.DeleteItems(0, m_GamesList.GetItemCount() ); 789 m_pGamesList->SetEnable(FALSE); 790 //XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, TRUE); 791 m_NetGamesListTimer.SetShow( TRUE ); 792 m_LabelNoGames.SetShow( FALSE ); 793 m_SavesList.InitFocus(m_iPad); 794 } 795 796 // are we back here because of a delete of a corrupt save? 797 798 if(app.GetCorruptSaveDeleted()) 799 { 800 // need to re-get the saves list and update the display 801 // clear the saves list 802 m_pSavesList->RemoveAllData(); 803 m_iSaveInfoC=0; 804 GetSaveInfo(); 805 app.SetCorruptSaveDeleted(false); 806 } 807 808 int iY = -1; 809 int iRB=-1; 810 if( DoesGamesListHaveFocus() ) 811 { 812 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 813 } 814 else if(DoesSavesListHaveFocus()) 815 { 816 if(ProfileManager.IsSignedInLive( m_iPad )) 817 { 818 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 819 } 820 821 if(StorageManager.GetSaveDisabled()) 822 { 823 iRB=IDS_TOOLTIPS_DELETESAVE; 824 } 825 else 826 { 827 // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename) 828 829 if(StorageManager.EnoughSpaceForAMinSaveGame()) 830 { 831 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 832 } 833 else 834 { 835 iRB=IDS_TOOLTIPS_DELETESAVE; 836 837 } 838 } 839 } 840 else if(DoesMashUpWorldHaveFocus()) 841 { 842 // If it's a mash-up pack world, give the Hide option 843 iRB=IDS_TOOLTIPS_HIDE; 844 } 845 846 int iLB = -1; 847 if(m_bInParty) 848 { 849 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 850 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 851 } 852 853 if(ProfileManager.IsFullVersion()==false ) 854 { 855 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, -1,-1,-1,iLB); 856 } 857 else if(StorageManager.GetSaveDisabled()) 858 { 859 // clear out the saves list, since the disable save may have happened in the load screen because of a device removal 860 861 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB); 862 } 863 else 864 { 865 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB); 866 } 867 868 return S_OK; 869} 870 871HRESULT CScene_MultiGameJoinLoad::OnNotifySelChanged(HXUIOBJ hObjSource, XUINotifySelChanged *pNotifySelChangedData, BOOL& bHandled) 872{ 873 874 if(m_bReady) 875 { 876 CXuiSceneBase::PlayUISFX(eSFX_Focus); 877 } 878 879 return S_OK; 880} 881 882 883HRESULT CScene_MultiGameJoinLoad::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled ) 884{ 885 //if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK; 886 887 if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY || 888 pTransition->dwTransType == XUI_TRANSITION_FROM || pTransition->dwTransType == XUI_TRANSITION_BACKFROM) 889 { 890 // 4J Stu - We may have had to unload our font renderer in this scene if one of the save files 891 // uses characters not in our font (eg asian chars) so restore our font renderer 892 // This will not do anything if our font renderer is already loaded 893 app.OverrideFontRenderer(true,true); 894 895 KillTimer(JOIN_LOAD_ONLINE_TIMER_ID); 896 } 897 else if(pTransition->dwTransType == XUI_TRANSITION_TO || pTransition->dwTransType == XUI_TRANSITION_BACKTO) 898 { 899 SetTimer(JOIN_LOAD_ONLINE_TIMER_ID,JOIN_LOAD_ONLINE_TIMER_TIME); 900 // 4J-PB - Need to check for installed DLC, which might have happened while you were on the info scene 901 if(pTransition->dwTransType == XUI_TRANSITION_BACKTO) 902 { 903 // Can't call this here because if you back out of the load info screen and then go back in and load a game, it will attempt to use the dlc as it's running a mount of the dlc 904 905 // block input if we're waiting for DLC to install, and wipe the saves list. The end of dlc mounting custom message will fill the list again 906 if(app.StartInstallDLCProcess(m_iPad)==false) 907 { 908 // not doing a mount, so re-enable input 909 m_bIgnoreInput=false; 910 } 911 else 912 { 913 m_bIgnoreInput=true; 914 m_pSavesList->RemoveAllData(); 915 m_SavesListTimer.SetShow( TRUE ); 916 } 917 } 918 } 919 920 return S_OK; 921} 922 923HRESULT CScene_MultiGameJoinLoad::OnFontRendererChange() 924{ 925 // update the tooltips 926 // if the saves list has focus, then we should show the Delete Save tooltip 927 // if the games list has focus, then we should the the View Gamercard tooltip 928 int iRB=-1; 929 int iY = -1; 930 if( DoesGamesListHaveFocus() ) 931 { 932 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 933 } 934 else if(DoesSavesListHaveFocus()) 935 { 936 if(ProfileManager.IsSignedInLive( m_iPad )) 937 { 938 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 939 } 940 if(StorageManager.GetSaveDisabled()) 941 { 942 iRB=IDS_TOOLTIPS_DELETESAVE; 943 } 944 else 945 { 946 if(StorageManager.EnoughSpaceForAMinSaveGame()) 947 { 948 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 949 } 950 else 951 { 952 iRB=IDS_TOOLTIPS_DELETESAVE; 953 } 954 } 955 } 956 else if(DoesMashUpWorldHaveFocus()) 957 { 958 // If it's a mash-up pack world, give the Hide option 959 iRB=IDS_TOOLTIPS_HIDE; 960 } 961 962 int iLB = -1; 963 if(m_bInParty) 964 { 965 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 966 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 967 } 968 969 if(ProfileManager.IsFullVersion()==false ) 970 { 971 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY,-1,-1,iLB,-1,-1,true); 972 } 973 else if(StorageManager.GetSaveDisabled()) 974 { 975 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB,-1,true); 976 } 977 else 978 { 979 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB,-1,true); 980 } 981 return S_OK; 982} 983 984HRESULT CScene_MultiGameJoinLoad::OnNotifySetFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled) 985{ 986 // update the tooltips 987 // if the saves list has focus, then we should show the Delete Save tooltip 988 // if the games list has focus, then we should the the View Gamercard tooltip 989 int iRB=-1; 990 int iY = -1; 991 if( DoesGamesListHaveFocus() ) 992 { 993 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 994 } 995 else if(DoesSavesListHaveFocus()) 996 { 997 if(ProfileManager.IsSignedInLive( m_iPad )) 998 { 999 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 1000 } 1001 if(StorageManager.GetSaveDisabled()) 1002 { 1003 iRB=IDS_TOOLTIPS_DELETESAVE; 1004 } 1005 else 1006 { 1007 if(StorageManager.EnoughSpaceForAMinSaveGame()) 1008 { 1009 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 1010 } 1011 else 1012 { 1013 iRB=IDS_TOOLTIPS_DELETESAVE; 1014 } 1015 } 1016 } 1017 else if(DoesMashUpWorldHaveFocus()) 1018 { 1019 // If it's a mash-up pack world, give the Hide option 1020 iRB=IDS_TOOLTIPS_HIDE; 1021 } 1022 1023 int iLB = -1; 1024 if(m_bInParty) 1025 { 1026 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 1027 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 1028 } 1029 1030 if(ProfileManager.IsFullVersion()==false ) 1031 { 1032 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY,-1,-1,iLB,-1); 1033 } 1034 else if(StorageManager.GetSaveDisabled()) 1035 { 1036 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB); 1037 } 1038 else 1039 { 1040 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB); 1041 } 1042 return S_OK; 1043} 1044 1045HRESULT CScene_MultiGameJoinLoad::OnNotifyKillFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled) 1046{ 1047 return S_OK; 1048} 1049 1050bool CScene_MultiGameJoinLoad::DoesSavesListHaveFocus() 1051{ 1052 HXUIOBJ hParentObj,hObj=TreeGetFocus(); 1053 1054 if(hObj!=NULL) 1055 { 1056 // get the parent and see if it's the saves list 1057 XuiElementGetParent(hObj,&hParentObj); 1058 if(hParentObj==m_SavesList.m_hObj) 1059 { 1060 // check it's not the first or second element (new world or tutorial) 1061 if(m_SavesList.GetCurSel()>(m_iDefaultButtonsC-1)) 1062 { 1063 return true; 1064 } 1065 } 1066 } 1067 return false; 1068} 1069 1070bool CScene_MultiGameJoinLoad::DoesMashUpWorldHaveFocus() 1071{ 1072 HXUIOBJ hParentObj,hObj=TreeGetFocus(); 1073 1074 if(hObj!=NULL) 1075 { 1076 // get the parent and see if it's the saves list 1077 XuiElementGetParent(hObj,&hParentObj); 1078 if(hParentObj==m_SavesList.m_hObj) 1079 { 1080 // check it's not the first or second element (new world or tutorial) 1081 if(m_SavesList.GetCurSel()>(m_iDefaultButtonsC-1)) 1082 { 1083 return false; 1084 } 1085 1086 if(m_SavesList.GetCurSel()>(m_iDefaultButtonsC - 1 - m_iMashUpButtonsC)) 1087 { 1088 return true; 1089 } 1090 else return false; 1091 } 1092 else return false; 1093 } 1094 return false; 1095} 1096 1097bool CScene_MultiGameJoinLoad::DoesGamesListHaveFocus() 1098{ 1099 HXUIOBJ hParentObj,hObj=TreeGetFocus(); 1100 1101 if(hObj!=NULL) 1102 { 1103 // get the parent and see if it's the saves list 1104 XuiElementGetParent(hObj,&hParentObj); 1105 if(hParentObj==m_pGamesList->m_hObj) 1106 { 1107 return true; 1108 } 1109 } 1110 return false; 1111} 1112 1113void CScene_MultiGameJoinLoad::UpdateGamesListCallback(LPVOID lpParam) 1114{ 1115 if(lpParam != NULL) 1116 { 1117 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad *) lpParam; 1118 // check this there's no save transfer in progress 1119 if(!pClass->m_bSaveTransferInProgress) 1120 { 1121 pClass->UpdateGamesList(); 1122 } 1123 } 1124} 1125 1126void CScene_MultiGameJoinLoad::UpdateGamesList() 1127{ 1128 if( m_bIgnoreInput ) return; 1129 1130 // if we're retrieving save info, don't show the list yet as we will be ignoring press events 1131 if(m_bRetrievingSaveInfo) 1132 { 1133 return; 1134 } 1135 1136 DWORD nIndex = -1; 1137 FriendSessionInfo *pSelectedSession = NULL; 1138 if(m_pGamesList->TreeHasFocus() && m_pGamesList->GetItemCount() > 0) 1139 { 1140 nIndex = m_pGamesList->GetCurSel(); 1141 pSelectedSession = currentSessions.at( nIndex ); 1142 } 1143 1144 SessionID selectedSessionId; 1145 if( pSelectedSession != NULL )selectedSessionId = pSelectedSession->sessionId; 1146 pSelectedSession = NULL; 1147 1148 for(AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end(); ++it) 1149 { 1150 delete (*it); 1151 } 1152 currentSessions.clear(); 1153 1154 m_NetGamesListTimer.SetShow( FALSE ); 1155 1156 // if the saves list has focus, then we should show the Delete Save tooltip 1157 // if the games list has focus, then we should show the View Gamercard tooltip 1158 int iRB=-1; 1159 int iY = -1; 1160 1161 if( DoesGamesListHaveFocus() ) 1162 { 1163 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 1164 } 1165 else if(DoesSavesListHaveFocus()) 1166 { 1167 if(ProfileManager.IsSignedInLive( m_iPad )) 1168 { 1169 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 1170 } 1171 if(StorageManager.GetSaveDisabled()) 1172 { 1173 iRB=IDS_TOOLTIPS_DELETESAVE; 1174 } 1175 else 1176 { 1177 if(StorageManager.EnoughSpaceForAMinSaveGame()) 1178 { 1179 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 1180 } 1181 else 1182 { 1183 iRB=IDS_TOOLTIPS_DELETESAVE; 1184 } 1185 } 1186 } 1187 else if(DoesMashUpWorldHaveFocus()) 1188 { 1189 // If it's a mash-up pack world, give the Hide option 1190 iRB=IDS_TOOLTIPS_HIDE; 1191 } 1192 1193 int iLB = -1; 1194 if(m_bInParty) 1195 { 1196 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 1197 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 1198 } 1199 1200 if(ProfileManager.IsFullVersion()==false ) 1201 { 1202 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY,-1,-1,iLB,-1); 1203 } 1204 else if(StorageManager.GetSaveDisabled()) 1205 { 1206 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB); 1207 } 1208 else 1209 { 1210 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB); 1211 } 1212 1213 currentSessions = *g_NetworkManager.GetSessionList( m_iPad, m_localPlayers, m_bShowingPartyGamesOnly ); 1214 1215 // Update the xui list displayed 1216 unsigned int xuiListSize = m_pGamesList->GetItemCount(); 1217 unsigned int filteredListSize = (unsigned int)currentSessions.size(); 1218 1219 BOOL gamesListHasFocus = m_pGamesList->TreeHasFocus(); 1220 1221 if(filteredListSize > 0) 1222 { 1223 if( !m_pGamesList->IsEnabled() ) 1224 { 1225 m_pGamesList->SetEnable(TRUE); 1226 //XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, FALSE); 1227 m_pGamesList->SetCurSel( 0 ); 1228 } 1229 m_LabelNoGames.SetShow( FALSE ); 1230 m_NetGamesListTimer.SetShow( FALSE ); 1231 } 1232 else 1233 { 1234 m_pGamesList->SetEnable(FALSE); 1235 //XuiElementSetDisableFocusRecursion(m_pGamesList->m_hObj, TRUE); 1236 m_NetGamesListTimer.SetShow( FALSE ); 1237 m_LabelNoGames.SetShow( TRUE ); 1238 1239 if( gamesListHasFocus ) m_pGamesList->InitFocus(m_iPad); 1240 } 1241 1242 // clear out the games list and re-fill 1243 m_pGamesList->RemoveAllData(); 1244 1245 if( filteredListSize > 0 ) 1246 { 1247 // Reset the focus to the selected session if it still exists 1248 unsigned int sessionIndex = 0; 1249 m_pGamesList->SetCurSel(0); 1250 1251 for( AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end(); ++it) 1252 { 1253 FriendSessionInfo *sessionInfo = *it; 1254 HXUIBRUSH hXuiBrush; 1255 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 1256 1257 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); 1258 1259 ListInfo.pwszText = sessionInfo->displayLabel; 1260 ListInfo.fEnabled = TRUE; 1261 ListInfo.iData = sessionIndex; 1262 m_pGamesList->AddData(ListInfo); 1263 // display an icon too 1264 1265 // Is this a default game or a texture pack game? 1266 if(sessionInfo->data.texturePackParentId!=0) 1267 { 1268 // Do we have the texture pack 1269 Minecraft *pMinecraft = Minecraft::GetInstance(); 1270 TexturePack *tp = pMinecraft->skins->getTexturePackById(sessionInfo->data.texturePackParentId); 1271 HRESULT hr; 1272 1273 DWORD dwImageBytes=0; 1274 PBYTE pbImageData=NULL; 1275 1276 if(tp==NULL) 1277 { 1278 DWORD dwBytes=0; 1279 PBYTE pbData=NULL; 1280 app.GetTPD(sessionInfo->data.texturePackParentId,&pbData,&dwBytes); 1281 1282 // is it in the tpd data ? 1283 app.GetFileFromTPD(eTPDFileType_Icon,pbData,dwBytes,&pbImageData,&dwImageBytes ); 1284 if(dwImageBytes > 0 && pbImageData) 1285 { 1286 hr=XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&hXuiBrush); 1287 m_pGamesList->UpdateGraphic(sessionIndex,hXuiBrush); 1288 } 1289 } 1290 else 1291 { 1292 pbImageData = tp->getPackIcon(dwImageBytes); 1293 if(dwImageBytes > 0 && pbImageData) 1294 { 1295 hr=XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&hXuiBrush); 1296 m_pGamesList->UpdateGraphic(sessionIndex,hXuiBrush); 1297 } 1298 } 1299 } 1300 else 1301 { 1302 // default texture pack 1303 XuiCreateTextureBrushFromMemory(m_DefaultMinecraftIconData,m_DefaultMinecraftIconSize,&hXuiBrush); 1304 m_pGamesList->UpdateGraphic(sessionIndex,hXuiBrush); 1305 } 1306 1307 1308 if(memcmp( &selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID) ) == 0) 1309 { 1310 m_pGamesList->SetCurSel(sessionIndex); 1311 break; 1312 } 1313 ++sessionIndex; 1314 } 1315 } 1316} 1317 1318void CScene_MultiGameJoinLoad::UpdateGamesList(DWORD dwNumResults, IQNetGameSearch *pGameSearch) 1319{ 1320 // We don't use the QNet callback, but could resurrect this if we ever do normal matchmaking, but updated to work as the function above 1321#if 0 1322 const XSESSION_SEARCHRESULT *pSearchResult; 1323 const XNQOSINFO * pxnqi; 1324 1325 if(m_searches>0) 1326 --m_searches; 1327 1328 if(m_searches==0) 1329 { 1330 m_NetGamesListTimer.SetShow( FALSE ); 1331 1332 // if the saves list has focus, then we should show the Delete Save tooltip 1333 // if the games list has focus, then we should show the View Gamercard tooltip 1334 int iRB=-1; 1335 int iY = -1; 1336 1337 if( DoesGamesListHaveFocus() ) 1338 { 1339 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 1340 } 1341 else if(DoesSavesListHaveFocus()) 1342 { 1343 iRB=IDS_TOOLTIPS_DELETESAVE; 1344 } 1345 1346 int iLB = -1; 1347 if(m_bInParty) 1348 { 1349 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES 1350 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 1351 } 1352 1353 if(ProfileManager.IsFullVersion()==false ) 1354 { 1355 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY,-1,-1,iLB,iRB); 1356 } 1357 else if(StorageManager.GetSaveDisabled()) 1358 { 1359 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB); 1360 } 1361 else 1362 { 1363 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB); 1364 } 1365 } 1366 1367 if( dwNumResults == 0 ) 1368 { 1369 if(m_searches==0 && m_GamesList.GetItemCount() == 0) 1370 { 1371 m_LabelNoGames.SetShow( TRUE ); 1372 } 1373 return; 1374 } 1375 1376 unsigned int startOffset = m_GamesList.GetItemCount(); 1377 //m_GamesList.InsertItems(startOffset,dwNumResults); 1378 //m_GamesList.SetEnable(TRUE); 1379 //XuiElementSetDisableFocusRecursion( m_GamesList.m_hObj, FALSE); 1380 1381 // Loop through all the results. 1382 for( DWORD dwResult = 0; dwResult < pGameSearch->GetNumResults(); dwResult++ ) 1383 { 1384 1385 pSearchResult = pGameSearch->GetSearchResultAtIndex( dwResult ); 1386 1387 // No room for us, so ignore it 1388 if(pSearchResult->dwOpenPublicSlots < m_localPlayers) 1389 continue; 1390 1391 FriendSessionInfo *sessionInfo = NULL; 1392 bool foundSession = false; 1393 for(AUTO_VAR(it, friendsSessions.begin()); it < friendsSessions.end(); ++it) 1394 { 1395 sessionInfo = *it; 1396 if(memcmp( &pSearchResult->info.sessionID, &sessionInfo->sessionId, sizeof(SessionID) ) == 0) 1397 { 1398 sessionInfo->searchResult = *pSearchResult; 1399 sessionInfo->displayLabel = new wchar_t[100]; 1400 foundSession = true; 1401 break; 1402 } 1403 } 1404 1405 // We received a search result for a session no longer in our list of friends sessions 1406 if(!foundSession) 1407 continue; 1408 1409 // Print some info about this result. 1410 //printf( "Search result %u:\n", dwResult ); 1411 //printf( " public slots open = %u, filled = %u\n", pSearchResult->dwOpenPublicSlots, pSearchResult->dwFilledPublicSlots ); 1412 //printf( " private slots open = %u, filled = %u\n", pSearchResult->dwOpenPrivateSlots, pSearchResult->dwFilledPrivateSlots ); 1413 1414 // See if this result was contacted successfully via QoS probes. 1415 pxnqi = pGameSearch->GetQosInfoAtIndex( dwResult ); 1416 if( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_CONTACTED ) 1417 { 1418 // Print the round trip time and the rough estimation of 1419 // bandwidth. 1420 app.DebugPrintf( " RTT min = %u, med = %u\n", pxnqi->wRttMinInMsecs, pxnqi->wRttMedInMsecs ); 1421 app.DebugPrintf( " bps up = %u, down = %u\n", pxnqi->dwUpBitsPerSec, pxnqi->dwDnBitsPerSec ); 1422 1423 if(pxnqi->cbData > 0) 1424 { 1425 sessionInfo->data = *(GameSessionData *)pxnqi->pbData; 1426 1427 wstring gamerName = convStringToWstring(sessionInfo->data.hostName); 1428 swprintf(sessionInfo->displayLabel,L"%ls's Game", gamerName.c_str() ); 1429 } 1430 else 1431 { 1432 swprintf(sessionInfo->displayLabel,L"Unknown host Game"); 1433 } 1434 1435 // If this host wasn't disabled use this one. 1436 if( !( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_DISABLED ) && sessionInfo->data.netVersion == MINECRAFT_NET_VERSION ) 1437 { 1438 //printf("This game is valid\n"); 1439 filteredResults.push_back(sessionInfo); 1440 m_GamesList.InsertItems(startOffset,1); 1441 m_GamesList.SetText(startOffset,sessionInfo->displayLabel); 1442 startOffset++; 1443 } 1444#ifndef _CONTENT_PACKAGE 1445 if( sessionInfo->data.netVersion != MINECRAFT_NET_VERSION ) 1446 { 1447 wprintf(L"%ls version of %d does not match our version of %d\n", sessionInfo->displayLabel, sessionInfo->data.netVersion, MINECRAFT_NET_VERSION); 1448 } 1449#endif 1450 } 1451 } 1452 1453 if( m_GamesList.GetItemCount() == 0) 1454 { 1455 m_LabelNoGames.SetShow( TRUE ); 1456 } 1457 else 1458 { 1459 m_GamesList.SetEnable(TRUE); 1460 XuiElementSetDisableFocusRecursion( m_GamesList.m_hObj, FALSE); 1461 if( DoesGamesListHaveFocus() ) 1462 { 1463 m_GamesList.SetCurSel(0); 1464 } 1465 } 1466#endif 1467} 1468 1469/*void CScene_MultiGameJoinLoad::UpdateGamesListLabels() 1470{ 1471 for( unsigned int i = 0; i < currentSessions.size(); ++i ) 1472 { 1473 FriendSessionInfo *sessionInfo = currentSessions.at(i); 1474 m_GamesList.SetText(i,sessionInfo->displayLabel); 1475 HXUIBRUSH hBrush; 1476 CXuiCtrl4JList::LIST_ITEM_INFO info = m_pGamesList->GetData(i); 1477 1478 // display an icon too 1479 XuiCreateTextureBrushFromMemory(m_DefaultMinecraftIconData,m_DefaultMinecraftIconSize,&hBrush); 1480 m_pGamesList->UpdateGraphic(i,hBrush); 1481 } 1482#if 0 1483 XUIRect xuiRect; 1484 HXUIOBJ item = XuiListGetItemControl(m_GamesList,0); 1485 1486 HXUIOBJ hObj=NULL; 1487 HXUIOBJ hTextPres=NULL; 1488 HRESULT hr=XuiControlGetVisual(item,&hObj); 1489 hr=XuiElementGetChildById(hObj,L"text_Label",&hTextPres); 1490 1491 unsigned char displayLabelViewableStartIndex = 0; 1492 for( unsigned int i = 0; i < currentSessions.size(); ++i ) 1493 { 1494 FriendSessionInfo *sessionInfo = currentSessions.at(i); 1495 1496 if(hTextPres != NULL ) 1497 { 1498 hr=XuiTextPresenterMeasureText(hTextPres, sessionInfo->displayLabel, &xuiRect); 1499 1500 float fWidth, fHeight; 1501 XuiElementGetBounds(hTextPres,&fWidth,&fHeight); 1502 int characters = (fWidth/xuiRect.right) * sessionInfo->displayLabelLength; 1503 1504 if( characters < sessionInfo->displayLabelLength ) 1505 { 1506 static wchar_t temp[100]; 1507 ZeroMemory(temp, (100)*sizeof(wchar_t)); 1508 wcsncpy_s( temp, sessionInfo->displayLabel+sessionInfo->displayLabelViewableStartIndex, characters ); 1509 m_GamesList.SetText(i,temp); 1510 sessionInfo->displayLabelViewableStartIndex++; 1511 if( sessionInfo->displayLabelViewableStartIndex >= sessionInfo->displayLabelLength ) sessionInfo->displayLabelViewableStartIndex = 0; 1512 } 1513 } 1514 } 1515#endif 1516}*/ 1517 1518void CScene_MultiGameJoinLoad::SearchForGameCallback(void *param, DWORD dwNumResults, IQNetGameSearch *pGameSearch) 1519{ 1520#if 0 1521 HXUIOBJ hObj = (HXUIOBJ)param; 1522 1523 void *pObj; 1524 XuiObjectFromHandle( hObj, &pObj); 1525 CScene_MultiGameJoinLoad *MultiGameJoinLoad = (CScene_MultiGameJoinLoad *)pObj; 1526 1527 MultiGameJoinLoad->UpdateGamesList(dwNumResults, pGameSearch); 1528#endif 1529} 1530 1531int CScene_MultiGameJoinLoad::DeviceSelectReturned(void *pParam,bool bContinue) 1532{ 1533 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 1534 //HRESULT hr; 1535 1536 if(bContinue==true) 1537 { 1538 // if the saves list has focus, then we should show the Delete Save tooltip 1539 // if the games list has focus, then we should show the View Gamercard tooltip 1540 int iRB=-1; 1541 int iY = -1; 1542 if( pClass->DoesGamesListHaveFocus() ) 1543 { 1544 iY = IDS_TOOLTIPS_VIEW_GAMERCARD; 1545 } 1546 else if(pClass->DoesSavesListHaveFocus()) 1547 { 1548 if(ProfileManager.IsSignedInLive( pClass->m_iPad )) 1549 { 1550 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 1551 } 1552 if(StorageManager.GetSaveDisabled()) 1553 { 1554 iRB=IDS_TOOLTIPS_DELETESAVE; 1555 } 1556 else 1557 { 1558 if(StorageManager.EnoughSpaceForAMinSaveGame()) 1559 { 1560 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 1561 } 1562 else 1563 { 1564 iRB=IDS_TOOLTIPS_DELETESAVE; 1565 } 1566 } 1567 } 1568 else if(pClass->DoesMashUpWorldHaveFocus()) 1569 { 1570 // If it's a mash-up pack world, give the Hide option 1571 iRB=IDS_TOOLTIPS_HIDE; 1572 } 1573 1574 int iLB = -1; 1575 if(pClass->m_bInParty) 1576 { 1577 if( pClass->m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 1578 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 1579 } 1580 1581 //BOOL bOnlineGame=pClass->m_CheckboxOnline.IsChecked(); 1582 1583 // refresh the saves list (if there is a device selected) 1584 1585 // clear out the list first 1586 1587 if(StorageManager.GetSaveDisabled()) 1588 { 1589 if(StorageManager.GetSaveDeviceSelected(pClass->m_iPad)) 1590 { 1591 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,iY,-1,-1,iLB,iRB); 1592 // saving is disabled, but we should still be able to load from a selected save device 1593 pClass->GetSaveInfo(); 1594 } 1595 else 1596 { 1597 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB); 1598 // clear the saves list 1599 pClass->m_pSavesList->RemoveAllData(); 1600 1601 pClass->m_iSaveInfoC=0; 1602 //pClass->m_iThumbnailsLoadedC=0; 1603 1604 pClass->AddDefaultButtons(); 1605 1606 pClass->m_SavesListTimer.SetShow( FALSE ); 1607 1608 pClass->m_pSavesList->SetCurSelVisible(0); 1609 } 1610 } 1611 else 1612 { 1613 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,iY,-1,-1,iLB,iRB); 1614 pClass->GetSaveInfo(); 1615 } 1616 } 1617 1618 // enable input again 1619 pClass->m_bIgnoreInput=false; 1620 1621 return 0; 1622} 1623 1624HRESULT CScene_MultiGameJoinLoad::OnTimer( XUIMessageTimer *pTimer, BOOL& bHandled ) 1625{ 1626 // 4J-PB - TODO - Don't think we can do this - if a 2nd player signs in here with an offline profile, the signed in LIVE player gets re-logged in, and bMultiplayerAllowed is false briefly 1627 switch(pTimer->nId) 1628 { 1629 1630 1631 case JOIN_LOAD_ONLINE_TIMER_ID: 1632 { 1633 XPARTY_USER_LIST partyList; 1634 1635 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1)) 1636 { 1637 m_bInParty=true; 1638 } 1639 else 1640 { 1641 m_bInParty=false; 1642 } 1643 1644 bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad); 1645 if(bMultiplayerAllowed != m_bMultiplayerAllowed) 1646 { 1647 if( bMultiplayerAllowed ) 1648 { 1649// m_CheckboxOnline.SetEnable(TRUE); 1650// m_CheckboxPrivate.SetEnable(TRUE); 1651 } 1652 else 1653 { 1654 m_bInParty = false; 1655 m_pGamesList->RemoveAllData(); 1656 //m_GamesList.DeleteItems(0, m_GamesList.GetItemCount() ); 1657 m_pGamesList->SetEnable(FALSE); 1658 //XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, TRUE); 1659 m_NetGamesListTimer.SetShow( TRUE ); 1660 m_LabelNoGames.SetShow( FALSE ); 1661 } 1662 1663 int iLB = -1; 1664 if(m_bInParty) 1665 { 1666 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES; 1667 else iLB = IDS_TOOLTIPS_PARTY_GAMES; 1668 } 1669 int iRB=-1; 1670 int iY=-1; 1671 1672 if( DoesGamesListHaveFocus() ) 1673 { 1674 } 1675 else if(DoesSavesListHaveFocus()) 1676 { 1677 if(ProfileManager.IsSignedInLive( m_iPad )) 1678 { 1679 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 1680 } 1681 1682 if(StorageManager.GetSaveDisabled()) 1683 { 1684 iRB=IDS_TOOLTIPS_DELETESAVE; 1685 } 1686 else 1687 { 1688 if(StorageManager.EnoughSpaceForAMinSaveGame()) 1689 { 1690 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 1691 } 1692 else 1693 { 1694 iRB=IDS_TOOLTIPS_DELETESAVE; 1695 } 1696 } 1697 } 1698 else if(DoesMashUpWorldHaveFocus()) 1699 { 1700 // If it's a mash-up pack world, give the Hide option 1701 iRB=IDS_TOOLTIPS_HIDE; 1702 } 1703 1704 if(ProfileManager.IsFullVersion()==false ) 1705 { 1706 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, -1,-1,-1,iLB); 1707 } 1708 else if(StorageManager.GetSaveDisabled()) 1709 { 1710 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,-1,-1,-1,iLB,iRB); 1711 } 1712 else 1713 { 1714 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE,iY,-1,-1,iLB,iRB); 1715 } 1716 m_bMultiplayerAllowed = bMultiplayerAllowed; 1717 } 1718 } 1719 break; 1720 case JOIN_LOAD_SEARCH_MINIMUM_TIMER_ID: 1721 { 1722 XuiKillTimer( m_hObj, JOIN_LOAD_SEARCH_MINIMUM_TIMER_ID ); 1723 m_NetGamesListTimer.SetShow( FALSE ); 1724 m_LabelNoGames.SetShow( TRUE ); 1725 } 1726 break; 1727 case JOIN_LOAD_SCROLL_GAME_NAMES_TIMER_ID: 1728 { 1729 // This is called by the gameslist callback function, so isn't needed on a timer 1730 //UpdateGamesListLabels(); 1731 } 1732 break; 1733 case CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID: 1734 { 1735 // also check for any new texture packs info being available 1736 // for each item in the mem list, check it's in the data list 1737 1738 //CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 1739 // for each iConfig, check if the data is available, and add it to the List, then remove it from the viConfig 1740 1741 for(int i=0;i<m_iTexturePacksNotInstalled;i++) 1742 { 1743 if(m_iConfigA[i]!=-1) 1744 { 1745 DWORD dwBytes=0; 1746 PBYTE pbData=NULL; 1747 //app.DebugPrintf("Retrieving iConfig %d from TPD\n",m_iConfigA[i]); 1748 1749 app.GetTPD(m_iConfigA[i],&pbData,&dwBytes); 1750 1751 if(dwBytes > 0 && pbData) 1752 { 1753 //update the games list 1754 UpdateGamesList(); 1755 1756 m_iConfigA[i]=-1; 1757 } 1758 } 1759 } 1760 bool bAllDone=true; 1761 for(int i=0;i<m_iTexturePacksNotInstalled;i++) 1762 { 1763 if(m_iConfigA[i]!=-1) 1764 { 1765 bAllDone = false; 1766 } 1767 } 1768 1769 if(bAllDone) 1770 { 1771 // kill this timer 1772 XuiKillTimer(m_hObj,CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID); 1773 } 1774 } 1775 break; 1776 } 1777 1778 return S_OK; 1779} 1780 1781/* 1782int CScene_MultiGameJoinLoad::LoadSaveDataReturned(void *pParam,bool bContinue) 1783{ 1784 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 1785 1786 if(bContinue==true) 1787 { 1788 bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()); 1789 1790 // 4J Stu - If we only have one controller connected, then don't show the sign-in UI again 1791 DWORD connectedControllers = 0; 1792 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) 1793 { 1794 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) ) ++connectedControllers; 1795 } 1796 1797 if(!isClientSide || connectedControllers == 1 || !RenderManager.IsHiDef()) 1798 { 1799 DWORD dwLocalUsersMask = CGameNetworkManager::GetLocalPlayerMask(ProfileManager.GetPrimaryPad()); 1800 1801 // No guest problems so we don't need to force a sign-in of players here 1802 StartGameFromSave(pClass, dwLocalUsersMask); 1803 } 1804 else 1805 { 1806 ProfileManager.RequestSignInUI(false, false, false, true, false,&CScene_MultiGameJoinLoad::StartGame_SignInReturned, pParam,ProfileManager.GetPrimaryPad()); 1807 } 1808 } 1809 else 1810 { 1811 pClass->m_bIgnoreInput=false; 1812 } 1813 return 0; 1814} 1815*/ 1816 1817int CScene_MultiGameJoinLoad::StartGame_SignInReturned(void *pParam,bool bContinue, int iPad) 1818{ 1819 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 1820 1821 if(bContinue==true) 1822 { 1823 // It's possible that the player has not signed in - they can back out 1824 if(ProfileManager.IsSignedIn(iPad)) 1825 { 1826 DWORD dwLocalUsersMask = 0; 1827 1828 for(unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) 1829 { 1830 if(ProfileManager.IsSignedIn(index) ) 1831 { 1832 dwLocalUsersMask |= CGameNetworkManager::GetLocalPlayerMask(index); 1833 } 1834 } 1835 StartGameFromSave(pClass, dwLocalUsersMask); 1836 } 1837 } 1838 else 1839 { 1840 pClass->m_bIgnoreInput=false; 1841 } 1842 return 0; 1843} 1844 1845// 4J Stu - Shared functionality that is the same whether we needed a quadrant sign-in or not 1846void CScene_MultiGameJoinLoad::StartGameFromSave(CScene_MultiGameJoinLoad* pClass, DWORD dwLocalUsersMask) 1847{ 1848 /*bool isClientSide = ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && pClass->m_CheckboxOnline.IsChecked() == TRUE; 1849 //bool isPrivate = pClass->m_CheckboxPrivate.IsChecked() == TRUE; 1850 1851 SenStatGameEvent(ProfileManager.GetPrimaryPad(),eTelemetryGameEvent_Load,Minecraft::GetInstance()->options->difficulty, isClientSide, ProfileManager.IsFullVersion(), 1,0 ); 1852 1853 g_NetworkManager.HostGame(dwLocalUsersMask,isClientSide,isPrivate,MINECRAFT_NET_MAX_PLAYERS,0); 1854 1855 LoadingInputParams *loadingParams = new LoadingInputParams(); 1856 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; 1857 loadingParams->lpParam = NULL; 1858 1859 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 1860 completionData->bShowBackground=TRUE; 1861 completionData->bShowLogo=TRUE; 1862 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; 1863 completionData->iPad = DEFAULT_XUI_MENU_USER; 1864 loadingParams->completionData = completionData; 1865 1866 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams);*/ 1867} 1868 1869int CScene_MultiGameJoinLoad::DeleteSaveDataReturned(void *pParam,bool bSuccess) 1870{ 1871 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 1872 1873 if(bSuccess==true) 1874 { 1875 // need to re-get the saves list and update the display 1876 // clear the saves list 1877 pClass->m_pSavesList->RemoveAllData(); 1878 pClass->m_iSaveInfoC=0; 1879 pClass->GetSaveInfo(); 1880 } 1881 1882 pClass->m_bIgnoreInput=false; 1883 1884 return 0; 1885} 1886 1887void CScene_MultiGameJoinLoad::LoadLevelGen(LevelGenerationOptions *levelGen) 1888{ 1889 // Load data from disc 1890 //File saveFile( L"Tutorial\\Tutorial" ); 1891 //LoadSaveFromDisk(&saveFile); 1892 1893 // clear out the app's terrain features list 1894 app.ClearTerrainFeaturePosition(); 1895 1896 StorageManager.ResetSaveData(); 1897 // Make our next save default to the name of the level 1898 StorageManager.SetSaveTitle(levelGen->getDefaultSaveName().c_str()); 1899 1900 bool isClientSide = false; 1901 bool isPrivate = false; 1902 int maxPlayers = MINECRAFT_NET_MAX_PLAYERS; 1903 1904 if( app.GetTutorialMode() ) 1905 { 1906 isClientSide = false; 1907 maxPlayers = 4; 1908 } 1909 1910 g_NetworkManager.HostGame(0,isClientSide,isPrivate,maxPlayers,0); 1911 1912 NetworkGameInitData *param = new NetworkGameInitData(); 1913 param->seed = 0; 1914 param->saveData = NULL; 1915 param->settings = app.GetGameHostOption( eGameHostOption_Tutorial ); 1916 param->levelGen = levelGen; 1917 1918 if(levelGen->requiresTexturePack()) 1919 { 1920 param->texturePackId = levelGen->getRequiredTexturePackId(); 1921 1922 Minecraft *pMinecraft = Minecraft::GetInstance(); 1923 pMinecraft->skins->selectTexturePackById(param->texturePackId); 1924 //pMinecraft->skins->updateUI(); 1925 } 1926 1927 LoadingInputParams *loadingParams = new LoadingInputParams(); 1928 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; 1929 loadingParams->lpParam = (LPVOID)param; 1930 1931 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 1932 completionData->bShowBackground=TRUE; 1933 completionData->bShowLogo=TRUE; 1934 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; 1935 completionData->iPad = DEFAULT_XUI_MENU_USER; 1936 loadingParams->completionData = completionData; 1937 1938 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 1939} 1940 1941void CScene_MultiGameJoinLoad::LoadSaveFromDisk(File *saveFile) 1942{ 1943 // we'll only be coming in here when the tutorial is loaded now 1944 1945 StorageManager.ResetSaveData(); 1946 1947 // Make our next save default to the name of the level 1948 StorageManager.SetSaveTitle(saveFile->getName().c_str()); 1949 1950 __int64 fileSize = saveFile->length(); 1951 FileInputStream fis(*saveFile); 1952 byteArray ba(fileSize); 1953 fis.read(ba); 1954 fis.close(); 1955 1956 bool isClientSide = false; 1957 bool isPrivate = false; 1958 int maxPlayers = MINECRAFT_NET_MAX_PLAYERS; 1959 1960 if( app.GetTutorialMode() ) 1961 { 1962 isClientSide = false; 1963 maxPlayers = 4; 1964 } 1965 1966 app.SetGameHostOption(eGameHostOption_GameType,GameType::CREATIVE->getId()); 1967 1968 g_NetworkManager.HostGame(0,isClientSide,isPrivate,maxPlayers,0); 1969 1970 LoadSaveDataThreadParam *saveData = new LoadSaveDataThreadParam(ba.data, ba.length, saveFile->getName()); 1971 1972 NetworkGameInitData *param = new NetworkGameInitData(); 1973 param->seed = 0; 1974 param->saveData = saveData; 1975 param->settings = app.GetGameHostOption( eGameHostOption_All ); 1976 1977 LoadingInputParams *loadingParams = new LoadingInputParams(); 1978 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc; 1979 loadingParams->lpParam = (LPVOID)param; 1980 1981 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 1982 completionData->bShowBackground=TRUE; 1983 completionData->bShowLogo=TRUE; 1984 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes; 1985 completionData->iPad = DEFAULT_XUI_MENU_USER; 1986 loadingParams->completionData = completionData; 1987 1988 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 1989} 1990 1991int CScene_MultiGameJoinLoad::DeleteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 1992{ 1993 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 1994 // results switched for this dialog 1995 if(result==C4JStorage::EMessage_ResultDecline) 1996 { 1997 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) 1998 { 1999 pClass->m_bIgnoreInput=false; 2000 } 2001 else 2002 { 2003 XCONTENT_DATA XContentData; 2004 StorageManager.GetSaveCacheFileInfo(pClass->m_iChangingSaveGameInfoIndex-pClass->m_iDefaultButtonsC,XContentData); 2005 StorageManager.DeleteSaveData(&XContentData,CScene_MultiGameJoinLoad::DeleteSaveDataReturned,pClass); 2006 pClass->m_SavesListTimer.SetShow( TRUE ); 2007 } 2008 } 2009 else 2010 { 2011 pClass->m_bIgnoreInput=false; 2012 } 2013 return 0; 2014} 2015 2016int CScene_MultiGameJoinLoad::SaveTransferDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 2017{ 2018 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2019 // results switched for this dialog 2020 if(result==C4JStorage::EMessage_ResultAccept) 2021 { 2022 // upload the save 2023 2024 // first load the save 2025 int iIndex=pClass->m_pSavesList->GetData(pClass->m_pSavesList->GetCurSel()).iIndex-pClass->m_iDefaultButtonsC; 2026 XCONTENT_DATA ContentData; 2027 2028 // 4J-PB - ensure we've switched to the right title group id for uploading to 2029 app.TMSPP_SetTitleGroupID(SAVETRANSFER_GROUP_ID); 2030 StorageManager.GetSaveCacheFileInfo(iIndex,ContentData); 2031 C4JStorage::ELoadGameStatus eLoadStatus=StorageManager.LoadSaveData(&ContentData,CScene_MultiGameJoinLoad::LoadSaveDataReturned,pClass); 2032 2033 pClass->m_bIgnoreInput=false; 2034 } 2035 else 2036 { 2037 pClass->m_bIgnoreInput=false; 2038 } 2039 return 0; 2040} 2041 2042int CScene_MultiGameJoinLoad::UploadSaveForXboxOneThreadProc( LPVOID lpParameter ) 2043{ 2044 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad *) lpParameter; 2045 Minecraft *pMinecraft = Minecraft::GetInstance(); 2046 2047 pMinecraft->progressRenderer->progressStart(IDS_SAVE_TRANSFER_TITLE); 2048 pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_UPLOADING ); 2049 2050 // Delete the marker file 2051 DeleteFile(pClass, "completemarker"); 2052 if(!WaitForTransferComplete(pClass)) return 0; 2053 2054 // Upload the save data 2055 { 2056 unsigned int uiSaveBytes; 2057 uiSaveBytes=StorageManager.GetSaveSize(); 2058 pClass->m_pbSaveTransferData=new BYTE [uiSaveBytes]; 2059 2060 StorageManager.GetSaveData(pClass->m_pbSaveTransferData,&uiSaveBytes); 2061 2062 app.DebugPrintf("Uploading save data (%d bytes)\n", uiSaveBytes); 2063 UploadFile(pClass, "savedata", pClass->m_pbSaveTransferData, uiSaveBytes); 2064 } 2065 2066 if(!WaitForTransferComplete(pClass)) return 0; 2067 if(pClass->m_bTransferFail) 2068 { 2069 // something went wrong, user has been informed 2070 pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_UPLOADFAILED ); 2071 return 0; 2072 } 2073 2074 // Upload the metadata and thumbnail 2075 { 2076 ByteArrayOutputStream baos; 2077 DataOutputStream dos(&baos); 2078 2079 LPCWSTR title = StorageManager.GetSaveTitle(); 2080 dos.writeUTF(title); 2081 2082 char szUniqueMapName[14]; 2083 StorageManager.GetSaveUniqueFilename(szUniqueMapName); 2084 dos.writeUTF(convStringToWstring(szUniqueMapName)); 2085 2086 { 2087 // set the save icon 2088 PBYTE pbImageData=NULL; 2089 DWORD dwImageBytes=0; 2090 XCONTENT_DATA XContentData; 2091 int iIndex=pClass->m_pSavesList->GetData(pClass->m_pSavesList->GetCurSel()).iIndex-pClass->m_iDefaultButtonsC; 2092 StorageManager.GetSaveCacheFileInfo(iIndex,XContentData); 2093 StorageManager.GetSaveCacheFileInfo(iIndex,&pbImageData,&dwImageBytes); 2094 2095 // if there is no thumbnail, retrieve the default one from the file. 2096 // Don't delete the image data after creating the xuibrush, since we'll use it in the rename of the save 2097 if(pbImageData==NULL) 2098 { 2099 DWORD dwResult=XContentGetThumbnail(ProfileManager.GetPrimaryPad(),&XContentData,NULL,&dwImageBytes,NULL); 2100 if(dwResult==ERROR_SUCCESS) 2101 { 2102 pClass->m_pbSaveTransferData = new BYTE[dwImageBytes]; 2103 pbImageData = pClass->m_pbSaveTransferData; // Copy pointer so that we can use the same name as the library owned one, but m_pbSaveTransferData will get deleted when done 2104 XContentGetThumbnail(ProfileManager.GetPrimaryPad(),&XContentData,pbImageData,&dwImageBytes,NULL); 2105 } 2106 } 2107 2108 dos.writeInt(dwImageBytes); 2109 2110 byteArray ba(pbImageData, dwImageBytes); 2111 dos.write(ba); 2112 } 2113 2114 pClass->m_pbSaveTransferData=new BYTE [baos.size()]; 2115 memcpy(pClass->m_pbSaveTransferData,baos.buf.data,baos.size()); 2116 2117 app.DebugPrintf("Uploading meta data (%d bytes)\n", baos.size()); 2118 UploadFile(pClass, "metadata", pClass->m_pbSaveTransferData, baos.size()); 2119 } 2120 2121 // Wait for metadata and thumbnail 2122 if(!WaitForTransferComplete(pClass)) return 0; 2123 if(pClass->m_bTransferFail) 2124 { 2125 // something went wrong, user has been informed 2126 pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_UPLOADFAILED ); 2127 return 0; 2128 } 2129 2130 // Upload the marker file 2131 { 2132 char singleByteData[1] = {1}; 2133 app.DebugPrintf("Uploading marker (%d bytes)\n", 1); 2134 UploadFile(pClass, "completemarker", &singleByteData, 1); 2135 } 2136 2137 // Wait for marker 2138 if(!WaitForTransferComplete(pClass)) return 0; 2139 if(pClass->m_bTransferFail) 2140 { 2141 // something went wrong, user has been informed 2142 pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_UPLOADFAILED ); 2143 2144 return 0; 2145 } 2146 // change text for completion confirmation 2147 pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_UPLOADCOMPLETE ); 2148 2149 // done 2150 return 0; 2151} 2152 2153void CScene_MultiGameJoinLoad::DeleteFile(CScene_MultiGameJoinLoad *pClass, char *filename) 2154{ 2155 pClass->m_fProgress=0.0f; 2156 pClass->m_bTransferComplete=false; 2157 2158 C4JStorage::ETMSStatus result = StorageManager.TMSPP_DeleteFile( 2159 ProfileManager.GetPrimaryPad(), 2160 filename, 2161 C4JStorage::TMS_FILETYPE_BINARY, 2162 &CScene_MultiGameJoinLoad::DeleteComplete, 2163 pClass, 2164 NULL); 2165 2166 if(result != C4JStorage::ETMSStatus_DeleteInProgress) 2167 { 2168 DeleteComplete(pClass,ProfileManager.GetPrimaryPad(), -1); 2169 } 2170} 2171 2172void CScene_MultiGameJoinLoad::UploadFile(CScene_MultiGameJoinLoad *pClass, char *filename, LPVOID data, DWORD size) 2173{ 2174 pClass->m_fProgress=0.0f; 2175 pClass->m_bTransferComplete=false; 2176 2177 C4JStorage::ETMSStatus result = StorageManager.TMSPP_WriteFileWithProgress( 2178 ProfileManager.GetPrimaryPad(), 2179 C4JStorage::eGlobalStorage_TitleUser, 2180 C4JStorage::TMS_FILETYPE_BINARY, 2181 C4JStorage::TMS_UGCTYPE_NONE, 2182 filename, 2183 (CHAR *)data, 2184 size, 2185 &CScene_MultiGameJoinLoad::TransferComplete,pClass, 0, 2186 &CScene_MultiGameJoinLoad::Progress,pClass); 2187 2188#ifdef _DEBUG_MENUS_ENABLED 2189 if(app.GetWriteSavesToFolderEnabled()) 2190 { 2191 File targetFileDir(L"GAME:\\FakeTMSPP"); 2192 if(!targetFileDir.exists()) targetFileDir.mkdir(); 2193 string path = string( wstringtofilename( targetFileDir.getPath() ) ).append("\\").append(filename); 2194 HANDLE hSaveFile = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_RANDOM_ACCESS, NULL); 2195 2196 DWORD numberOfBytesWritten = 0; 2197 WriteFile( hSaveFile,data,size,&numberOfBytesWritten,NULL); 2198 assert(numberOfBytesWritten == size); 2199 2200 CloseHandle(hSaveFile); 2201 } 2202#endif 2203 2204 if(result != C4JStorage::ETMSStatus_WriteInProgress) 2205 { 2206 TransferComplete(pClass,ProfileManager.GetPrimaryPad(), -1); 2207 } 2208} 2209 2210bool CScene_MultiGameJoinLoad::WaitForTransferComplete( CScene_MultiGameJoinLoad *pClass ) 2211{ 2212 Minecraft *pMinecraft = Minecraft::GetInstance(); 2213 // loop until complete 2214 while(pClass->m_bTransferComplete==false) 2215 { 2216 // check for a cancel 2217 if(pClass->m_bSaveTransferInProgress==false) 2218 { 2219 // cancelled 2220 return false; 2221 } 2222 Sleep(50); 2223 // update the progress 2224 pMinecraft->progressRenderer->progressStagePercentage((unsigned int)(pClass->m_fProgress*100.0f)); 2225 } 2226 2227 // was there a transfer error? 2228 2229 return true; 2230} 2231 2232int CScene_MultiGameJoinLoad::SaveOptionsDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 2233{ 2234 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2235 2236 // results switched for this dialog 2237 // EMessage_ResultAccept means cancel 2238 if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultThirdOption) 2239 { 2240 if(result==C4JStorage::EMessage_ResultDecline) // rename 2241 { 2242 ZeroMemory(pClass->m_wchNewName,sizeof(WCHAR)*XCONTENT_MAX_DISPLAYNAME_LENGTH); 2243 // bring up a keyboard 2244 InputManager.RequestKeyboard(IDS_RENAME_WORLD_TITLE,L"",IDS_RENAME_WORLD_TEXT,iPad,pClass->m_wchNewName,XCONTENT_MAX_DISPLAYNAME_LENGTH,&CScene_MultiGameJoinLoad::KeyboardReturned,pClass,C_4JInput::EKeyboardMode_Default,app.GetStringTable()); 2245 } 2246 else // delete 2247 { 2248 // delete the save game 2249 // Have to ask the player if they are sure they want to delete this game 2250 UINT uiIDA[2]; 2251 uiIDA[0]=IDS_CONFIRM_CANCEL; 2252 uiIDA[1]=IDS_CONFIRM_OK; 2253 StorageManager.RequestMessageBox(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, iPad,&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,pClass, app.GetStringTable()); 2254 //pClass->m_bIgnoreInput=false; 2255 } 2256 } 2257 else 2258 { 2259 pClass->m_bIgnoreInput=false; 2260 } 2261 return 0; 2262} 2263 2264int CScene_MultiGameJoinLoad::LoadSaveDataReturned(void *pParam,bool bContinue) 2265{ 2266 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2267 2268 if(bContinue==true) 2269 { 2270 pClass->m_bSaveTransferInProgress=true; 2271 LoadingInputParams *loadingParams = new LoadingInputParams(); 2272 loadingParams->func = &CScene_MultiGameJoinLoad::UploadSaveForXboxOneThreadProc; 2273 loadingParams->lpParam = (LPVOID)pParam; 2274 2275 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); 2276 completionData->bShowBackground=TRUE; 2277 completionData->bShowLogo=TRUE; 2278 completionData->type = e_ProgressCompletion_NavigateBack; 2279 completionData->iPad = DEFAULT_XUI_MENU_USER; 2280 completionData->bRequiresUserAction=TRUE; 2281 loadingParams->completionData = completionData; 2282 2283 loadingParams->cancelFunc=&CScene_MultiGameJoinLoad::CancelSaveUploadCallback; 2284 loadingParams->completeFunc=&CScene_MultiGameJoinLoad::SaveUploadCompleteCallback; 2285 loadingParams->m_cancelFuncParam=pClass; 2286 loadingParams->m_completeFuncParam=pClass; 2287 loadingParams->cancelText=IDS_TOOLTIPS_CANCEL; 2288 2289 app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams); 2290 } 2291 else 2292 { 2293 // switch back to the normal title group id 2294 app.TMSPP_SetTitleGroupID(GROUP_ID); 2295 2296 // the save is corrupt! 2297 2298 pClass->SetShow( TRUE ); 2299 pClass->m_bIgnoreInput=false; 2300 2301 // give the option to delete the save 2302 UINT uiIDA[2]; 2303 uiIDA[0]=IDS_CONFIRM_CANCEL; 2304 uiIDA[1]=IDS_CONFIRM_OK; 2305 StorageManager.RequestMessageBox(IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE, IDS_CORRUPT_OR_DAMAGED_SAVE_TEXT, uiIDA, 2, 2306 pClass->m_iPad,&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,pClass, app.GetStringTable()); 2307 2308 } 2309 2310 return 0; 2311} 2312 2313int CScene_MultiGameJoinLoad::Progress(void *pParam,float fProgress) 2314{ 2315 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2316 2317 app.DebugPrintf("Progress - %f\n",fProgress); 2318 pClass->m_fProgress=fProgress; 2319 return 0; 2320} 2321 2322int CScene_MultiGameJoinLoad::TransferComplete(void *pParam,int iPad, int iResult) 2323{ 2324 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2325 2326 delete [] pClass->m_pbSaveTransferData; 2327 pClass->m_pbSaveTransferData = NULL; 2328 if(iResult!=0) 2329 { 2330 // There was a transfer fail 2331 // Display a dialog 2332 UINT uiIDA[1]; 2333 uiIDA[0]=IDS_CONFIRM_OK; 2334 StorageManager.RequestMessageBox(IDS_SAVE_TRANSFER_TITLE, IDS_SAVE_TRANSFER_UPLOADFAILED, uiIDA, 1, ProfileManager.GetPrimaryPad(),NULL,NULL,app.GetStringTable()); 2335 pClass->m_bTransferFail=true; 2336 } 2337 else 2338 { 2339 pClass->m_bTransferFail=false; 2340 } 2341 pClass->m_bTransferComplete=true; 2342 //pClass->m_bSaveTransferInProgress=false; 2343 return 0; 2344} 2345 2346int CScene_MultiGameJoinLoad::DeleteComplete(void *pParam,int iPad, int iResult) 2347{ 2348 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2349 pClass->m_bTransferComplete=true; 2350 return 0; 2351} 2352 2353int CScene_MultiGameJoinLoad::KeyboardReturned(void *pParam,bool bSet) 2354{ 2355 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2356 HRESULT hr = S_OK; 2357 2358 // if the user has left the name empty, treat this as backing out 2359 if((pClass->m_wchNewName[0]!=0) && bSet) 2360 { 2361#ifdef _XBOX 2362 XCONTENT_DATA XContentData; 2363 StorageManager.GetSaveCacheFileInfo(pClass->m_iChangingSaveGameInfoIndex-pClass->m_iDefaultButtonsC,XContentData); 2364 2365 C4JStorage::ELoadGameStatus eLoadStatus=StorageManager.LoadSaveData(&XContentData,CScene_MultiGameJoinLoad::LoadSaveDataForRenameReturned,pClass); 2366 2367 if(eLoadStatus==C4JStorage::ELoadGame_DeviceRemoved) 2368 { 2369 // disable saving 2370 StorageManager.SetSaveDisabled(true); 2371 StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),false); 2372 UINT uiIDA[1]; 2373 uiIDA[0]=IDS_OK; 2374 StorageManager.RequestMessageBox(IDS_STORAGEDEVICEPROBLEM_TITLE, IDS_FAILED_TO_LOADSAVE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::DeviceRemovedDialogReturned,pClass); 2375 } 2376#else 2377 // rename the save 2378 2379#endif 2380 } 2381 else 2382 { 2383 pClass->m_bIgnoreInput=false; 2384 } 2385 2386 return hr; 2387} 2388 2389int CScene_MultiGameJoinLoad::LoadSaveDataForRenameReturned(void *pParam,bool bContinue) 2390{ 2391 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2392#ifdef _XBOX 2393 if(bContinue==true) 2394 { 2395 // set the save icon 2396 PBYTE pbImageData=NULL; 2397 DWORD dwImageBytes=0; 2398 HXUIBRUSH hXuiBrush; 2399 XCONTENT_DATA XContentData; 2400 StorageManager.GetSaveCacheFileInfo(pClass->m_iChangingSaveGameInfoIndex-pClass->m_iDefaultButtonsC,XContentData); 2401 StorageManager.GetSaveCacheFileInfo(pClass->m_iChangingSaveGameInfoIndex-pClass->m_iDefaultButtonsC,&pbImageData,&dwImageBytes); 2402 2403 // if there is no thumbnail, retrieve the default one from the file. 2404 // Don't delete the image data after creating the xuibrush, since we'll use it in the rename of the save 2405 if(pbImageData==NULL) 2406 { 2407 DWORD dwResult=XContentGetThumbnail(ProfileManager.GetPrimaryPad(),&XContentData,NULL,&dwImageBytes,NULL); 2408 if(dwResult==ERROR_SUCCESS) 2409 { 2410 pbImageData = new BYTE[dwImageBytes]; 2411 XContentGetThumbnail(ProfileManager.GetPrimaryPad(),&XContentData,pbImageData,&dwImageBytes,NULL); 2412 XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&hXuiBrush); 2413 } 2414 } 2415 else 2416 { 2417 XuiCreateTextureBrushFromMemory(pbImageData,dwImageBytes,&hXuiBrush); 2418 } 2419 // save the data with this icon 2420 StorageManager.CopySaveDataToNewSave( pbImageData,dwImageBytes,pClass->m_wchNewName,&CScene_MultiGameJoinLoad::CopySaveReturned,pClass); 2421 } 2422 else 2423#endif 2424 { 2425 //pClass->SetShow( TRUE ); 2426 pClass->m_bIgnoreInput=false; 2427 } 2428 return 0; 2429} 2430 2431int CScene_MultiGameJoinLoad::CopySaveReturned(void *pParam,bool bResult) 2432{ 2433 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam; 2434#ifdef _XBOX 2435 if(bResult) 2436 { 2437 // and delete the old save 2438 XCONTENT_DATA XContentData; 2439 StorageManager.GetSaveCacheFileInfo(pClass->m_iChangingSaveGameInfoIndex-pClass->m_iDefaultButtonsC,XContentData); 2440 StorageManager.DeleteSaveData(&XContentData,CScene_MultiGameJoinLoad::DeleteSaveDataReturned,pClass); 2441 pClass->m_SavesListTimer.SetShow( TRUE ); 2442 } 2443 else 2444#endif 2445 { 2446 //pClass->SetShow( TRUE ); 2447 pClass->m_bIgnoreInput=false; 2448 } 2449 2450 return 0; 2451} 2452 2453int CScene_MultiGameJoinLoad::TexturePackDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) 2454{ 2455 CScene_MultiGameJoinLoad *pClass = (CScene_MultiGameJoinLoad *)pParam; 2456 2457 // Exit with or without saving 2458 // Decline means install full version of the texture pack in this dialog 2459 if(result==C4JStorage::EMessage_ResultDecline || result==C4JStorage::EMessage_ResultAccept) 2460 { 2461 // we need to enable background downloading for the DLC 2462 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW); 2463 2464 ULONGLONG ullOfferID_Full; 2465 ULONGLONG ullIndexA[1]; 2466 app.GetDLCFullOfferIDForPackID(pClass->m_initData->selectedSession->data.texturePackParentId,&ullOfferID_Full); 2467 2468 if( result==C4JStorage::EMessage_ResultAccept ) // Full version 2469 { 2470 ullIndexA[0]=ullOfferID_Full; 2471 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); 2472 2473 } 2474 else // trial version 2475 { 2476 // if there is no trial version, this is a Cancel 2477 DLC_INFO *pDLCInfo=app.GetDLCInfoForFullOfferID(ullOfferID_Full); 2478 if(pDLCInfo->ullOfferID_Trial!=0LL) 2479 { 2480 ullIndexA[0]=pDLCInfo->ullOfferID_Trial; 2481 StorageManager.InstallOffer(1,ullIndexA,NULL,NULL); 2482 } 2483 } 2484 } 2485 pClass->m_bIgnoreInput=false; 2486 return 0; 2487} 2488 2489HRESULT CScene_MultiGameJoinLoad::OnCustomMessage_DLCInstalled() 2490{ 2491 // mounted DLC may have changed 2492 2493 if(app.StartInstallDLCProcess(m_iPad)==false) 2494 { 2495 // not doing a mount, so re-enable input 2496 m_bIgnoreInput=false; 2497 } 2498 else 2499 { 2500 m_bIgnoreInput=true; 2501 // clear out the saves list and re-fill 2502 2503 m_pSavesList->RemoveAllData(); 2504 m_SavesListTimer.SetShow( TRUE ); 2505 } 2506 // this will send a CustomMessage_DLCMountingComplete when done 2507 return S_OK; 2508} 2509 2510HRESULT CScene_MultiGameJoinLoad::OnCustomMessage_DLCMountingComplete() 2511{ 2512 2513 VOID *pObj; 2514 XuiObjectFromHandle( m_SavesList, &pObj ); 2515 m_pSavesList = (CXuiCtrl4JList *)pObj; 2516 2517 m_iChangingSaveGameInfoIndex = 0; 2518 2519 m_generators = app.getLevelGenerators(); 2520 m_iDefaultButtonsC = 0; 2521 m_iMashUpButtonsC = 0; 2522 XPARTY_USER_LIST partyList; 2523 2524 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1)) 2525 { 2526 m_bInParty=true; 2527 } 2528 else 2529 { 2530 m_bInParty=false; 2531 } 2532 2533 int iLB = -1; 2534 2535 int iY=-1; 2536 if(DoesSavesListHaveFocus()) 2537 { 2538 if(ProfileManager.IsSignedInLive( m_iPad )) 2539 { 2540 iY=IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE; 2541 } 2542 } 2543 if(m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES; 2544 // check if we're in the trial version 2545 if(ProfileManager.IsFullVersion()==false) 2546 { 2547 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK, -1, -1, -1, -1,iLB); 2548 2549 AddDefaultButtons(); 2550 2551 m_pSavesList->SetCurSelVisible(0); 2552 } 2553 else if(StorageManager.GetSaveDisabled()) 2554 { 2555 if(StorageManager.GetSaveDeviceSelected(m_iPad)) 2556 { 2557 // saving is disabled, but we should still be able to load from a selected save device 2558 2559 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,iY,-1,-1,iLB,IDS_TOOLTIPS_DELETESAVE); 2560 2561 GetSaveInfo(); 2562 } 2563 else 2564 { 2565 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB); 2566 2567 AddDefaultButtons(); 2568 m_SavesListTimer.SetShow( FALSE ); 2569 2570 m_pSavesList->SetCurSelVisible(0); 2571 } 2572 } 2573 else 2574 { 2575 // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename) 2576 bool bCanRename = StorageManager.EnoughSpaceForAMinSaveGame(); 2577 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_CHANGEDEVICE,iY,-1,-1,-1,bCanRename?IDS_TOOLTIPS_SAVEOPTIONS:IDS_TOOLTIPS_DELETESAVE); 2578 2579 GetSaveInfo(); 2580 } 2581 2582 m_bIgnoreInput=false; 2583 app.m_dlcManager.checkForCorruptDLCAndAlert(); 2584 return S_OK; 2585} 2586 2587/* 2588void CScene_MultiGameJoinLoad::UpdateTooltips() 2589{ 2590 int iA=IDS_TOOLTIPS_SELECT; 2591 int iB=IDS_TOOLTIPS_BACK; 2592 int iX=-1; 2593 int iY=-1 2594 int iLB = -1; 2595 XPARTY_USER_LIST partyList; 2596 2597 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1)) 2598 { 2599 m_bInParty=true; 2600 } 2601 else 2602 { 2603 m_bInParty=false; 2604 } 2605 2606 if(m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES; 2607 2608 if(ProfileManager.IsFullVersion()==false) 2609 { 2610 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK, -1, -1, -1, -1,iLB); 2611 } 2612 else if(StorageManager.GetSaveDisabled()) 2613 { 2614 if(StorageManager.GetSaveDeviceSelected(m_iPad)) 2615 { 2616 // saving is disabled, but we should still be able to load from a selected save device 2617 iX=IDS_TOOLTIPS_CHANGEDEVICE; 2618 iRB=IDS_TOOLTIPS_DELETESAVE; 2619 } 2620 else 2621 { 2622 iX=IDS_TOOLTIPS_SELECTDEVICE; 2623 } 2624 } 2625 else 2626 { 2627 // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename) 2628 bool bCanRename = StorageManager.EnoughSpaceForAMinSaveGame(); 2629 2630 if(bCanRename) 2631 { 2632 iRB=IDS_TOOLTIPS_SAVEOPTIONS; 2633 } 2634 else 2635 { 2636 iRB=IDS_TOOLTIPS_DELETESAVE; 2637 } 2638 } 2639 2640 ui.SetTooltips( DEFAULT_XUI_MENU_USER, iA,iB, iX, iY, iLT, iRT,iLB, iRB); 2641} 2642*/ 2643 2644 2645 2646#ifdef _XBOX 2647bool CScene_MultiGameJoinLoad::GetSavesInfoCallback(LPVOID pParam,int iTotalSaveInfoC, C4JStorage::CACHEINFOSTRUCT *InfoA, int iPad, HRESULT hResult) 2648{ 2649 CScene_MultiGameJoinLoad *pClass=(CScene_MultiGameJoinLoad *)pParam; 2650 CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; 2651 PBYTE pbImageData=(PBYTE)InfoA; 2652 PBYTE pbCurrentImagePtr; 2653 HXUIBRUSH hXuiBrush; 2654 HRESULT hr; 2655 2656 // move the image data pointer to the right place 2657 if(iTotalSaveInfoC!=0) 2658 { 2659 pbImageData+=sizeof(C4JStorage::CACHEINFOSTRUCT)*iTotalSaveInfoC; 2660 } 2661 2662 pClass->m_SavesListTimer.SetShow( FALSE ); 2663 pClass->m_SavesList.SetEnable(TRUE); 2664 2665 pClass->AddDefaultButtons(); 2666 2667 for(int i=0;i<iTotalSaveInfoC;i++) 2668 { 2669 ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); 2670 // Add these to the save list 2671 if(!(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled())) 2672 { 2673 // if the save is corrupt, display this instead of the title 2674 if(InfoA[i].dwImageBytes==0) 2675 { 2676 ListInfo.pwszText=app.GetString(IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE); 2677 ListInfo.bIsDamaged=true; 2678 } 2679 else 2680 { 2681 ListInfo.pwszText=InfoA[i].wchDisplayName; 2682 ListInfo.bIsDamaged=false; 2683 } 2684 ListInfo.fEnabled=TRUE; 2685 ListInfo.iData = -1; 2686 2687 pClass->m_pSavesList->AddData(ListInfo,-1); 2688 2689 // update the graphic on the list item 2690 2691 // if there is no thumbnail, this is a corrupt file 2692 if(InfoA[i].dwImageBytes!=0) 2693 { 2694 pbCurrentImagePtr=pbImageData+InfoA[i].dwImageOffset; 2695 hr=XuiCreateTextureBrushFromMemory(pbCurrentImagePtr,InfoA[i].dwImageBytes,&hXuiBrush); 2696 pClass->m_pSavesList->UpdateGraphic(i+pClass->m_iDefaultButtonsC,hXuiBrush ); 2697 } 2698 else 2699 { 2700 // we could put in a damaged save icon here 2701 const DWORD LOCATOR_SIZE = 256; // Use this to allocate space to hold a ResourceLocator string 2702 WCHAR szResourceLocator[ LOCATOR_SIZE ]; 2703 const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(NULL); 2704 2705 swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls",c_ModuleHandle,L"media", L"media/Graphics/MinecraftBrokenIcon.png"); 2706 2707 XuiCreateTextureBrush(szResourceLocator,&hXuiBrush); 2708 pClass->m_pSavesList->UpdateGraphic(i+pClass->m_iDefaultButtonsC,hXuiBrush ); 2709 } 2710 } 2711 } 2712 2713 pClass->m_iSaveInfoC=iTotalSaveInfoC; 2714 2715 // If there are some saves, then set the focus to be on the most recent one, which will be the first one after the create and tutorial 2716 if(iTotalSaveInfoC>0) 2717 { 2718 pClass->m_pSavesList->SetCurSelVisible(pClass->m_iDefaultButtonsC); 2719 pClass->m_bReady=true; 2720 } 2721 2722 pClass->m_bRetrievingSaveInfo=false; 2723 2724 // It's possible that the games list is updated but we haven't displayed it yet as we were still waiting on saves list to load 2725 // This is to fix a bug where joining a game before the saves list has loaded causes a crash when this callback is called 2726 // as the scene no longer exists 2727 pClass->UpdateGamesList(); 2728 2729 // Fix for #45154 - Frontend: DLC: Content can only be downloaded from the frontend if you have not joined/exited multiplayer 2730 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO); 2731 2732 return false; 2733} 2734#else 2735int CScene_MultiGameJoinLoad::GetSavesInfoCallback(LPVOID lpParam,const bool) 2736{ 2737 return true; 2738} 2739#endif 2740 2741void CScene_MultiGameJoinLoad::CancelSaveUploadCallback(LPVOID lpParam) 2742{ 2743 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad *) lpParam; 2744 2745 StorageManager.TMSPP_CancelWriteFileWithProgress(pClass->m_iPad); 2746 2747 pClass->m_bSaveTransferInProgress=false; 2748 2749 // change back to the normal title group id 2750 app.TMSPP_SetTitleGroupID(GROUP_ID); 2751// app.getRemoteStorage()->abort(); 2752// pClass->m_eSaveUploadState = eSaveUpload_Idle; 2753 2754 UINT uiIDA[1] = { IDS_CONFIRM_OK }; 2755 ui.RequestMessageBox(IDS_XBONE_CANCEL_UPLOAD_TITLE, IDS_XBONE_CANCEL_UPLOAD_TEXT, uiIDA, 1, pClass->m_iPad, NULL, NULL, app.GetStringTable()); 2756} 2757 2758void CScene_MultiGameJoinLoad::SaveUploadCompleteCallback(LPVOID lpParam) 2759{ 2760 CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad *) lpParam; 2761 2762 pClass->m_bSaveTransferInProgress=false; 2763 // change back to the normal title group id 2764 app.TMSPP_SetTitleGroupID(GROUP_ID); 2765 // app.getRemoteStorage()->abort(); 2766 // pClass->m_eSaveUploadState = eSaveUpload_Idle; 2767}