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 "UI.h"
3#include "UIScene_LoadOrJoinMenu.h"
4
5#include "..\..\..\Minecraft.World\StringHelpers.h"
6#include "..\..\..\Minecraft.World\net.minecraft.world.item.h"
7#include "..\..\..\Minecraft.World\net.minecraft.world.level.h"
8#include "..\..\..\Minecraft.World\net.minecraft.world.level.chunk.storage.h"
9#include "..\..\..\Minecraft.World\ConsoleSaveFile.h"
10#include "..\..\..\Minecraft.World\ConsoleSaveFileOriginal.h"
11#include "..\..\ProgressRenderer.h"
12#include "..\..\MinecraftServer.h"
13#include "..\..\TexturePackRepository.h"
14#include "..\..\TexturePack.h"
15#include "..\Network\SessionInfo.h"
16#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
17#include "Common\Network\Sony\SonyHttp.h"
18#include "Common\Network\Sony\SonyRemoteStorage.h"
19#include "DLCTexturePack.h"
20#endif
21#if defined(__ORBIS__) || defined(__PSVITA__)
22#include <ces.h>
23#endif
24#ifdef __PSVITA__
25#include "message_dialog.h"
26#endif
27
28
29#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
30unsigned long UIScene_LoadOrJoinMenu::m_ulFileSize=0L;
31wstring UIScene_LoadOrJoinMenu::m_wstrStageText=L"";
32bool UIScene_LoadOrJoinMenu::m_bSaveTransferRunning = false;
33#endif
34
35
36#define JOIN_LOAD_ONLINE_TIMER_ID 0
37#define JOIN_LOAD_ONLINE_TIMER_TIME 100
38
39#ifdef _XBOX
40#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID 3
41#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 50
42#endif
43
44#ifdef _XBOX_ONE
45UIScene_LoadOrJoinMenu::ESaveTransferFiles UIScene_LoadOrJoinMenu::s_eSaveTransferFile;
46unsigned long UIScene_LoadOrJoinMenu::s_ulFileSize=0L;
47byteArray UIScene_LoadOrJoinMenu::s_transferData = byteArray();
48wstring UIScene_LoadOrJoinMenu::m_wstrStageText=L"";
49
50#ifdef _DEBUG_MENUS_ENABLED
51C4JStorage::SAVETRANSFER_FILE_DETAILS UIScene_LoadOrJoinMenu::m_debugTransferDetails;
52#endif
53#endif
54
55int UIScene_LoadOrJoinMenu::LoadSaveDataThumbnailReturned(LPVOID lpParam,PBYTE pbThumbnail,DWORD dwThumbnailBytes)
56{
57 UIScene_LoadOrJoinMenu *pClass= (UIScene_LoadOrJoinMenu *)lpParam;
58
59 app.DebugPrintf("Received data for save thumbnail\n");
60
61 if(pbThumbnail && dwThumbnailBytes)
62 {
63 pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData = new BYTE[dwThumbnailBytes];
64 memcpy(pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData, pbThumbnail, dwThumbnailBytes);
65 pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].dwThumbnailSize = dwThumbnailBytes;
66 }
67 else
68 {
69 pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData = NULL;
70 pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].dwThumbnailSize = 0;
71 app.DebugPrintf("Save thumbnail data is NULL, or has size 0\n");
72 }
73 pClass->m_bSaveThumbnailReady = true;
74
75 return 0;
76}
77
78int UIScene_LoadOrJoinMenu::LoadSaveCallback(LPVOID lpParam,bool bRes)
79{
80 //UIScene_LoadOrJoinMenu *pClass= (UIScene_LoadOrJoinMenu *)lpParam;
81 // Get the save data now
82 if(bRes)
83 {
84 app.DebugPrintf("Loaded save OK\n");
85 }
86 return 0;
87}
88
89UIScene_LoadOrJoinMenu::UIScene_LoadOrJoinMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer)
90{
91 // Setup all the Iggy references we need for this scene
92 initialiseMovie();
93 app.SetLiveLinkRequired( true );
94
95 m_iRequestingThumbnailId = 0;
96 m_iSaveInfoC=0;
97 m_bIgnoreInput = false;
98 m_bShowingPartyGamesOnly = false;
99 m_bInParty = false;
100 m_currentSessions = NULL;
101 m_iState=e_SavesIdle;
102 //m_bRetrievingSaveInfo=false;
103
104 m_buttonListSaves.init(eControl_SavesList);
105 m_buttonListGames.init(eControl_GamesList);
106
107 m_labelSavesListTitle.init( IDS_START_GAME );
108 m_labelJoinListTitle.init( IDS_JOIN_GAME );
109 m_labelNoGames.init( IDS_NO_GAMES_FOUND );
110 m_labelNoGames.setVisible( false );
111 m_controlSavesTimer.setVisible( true );
112 m_controlJoinTimer.setVisible( true );
113
114
115#if defined(_XBOX_ONE) || defined(__ORBIS__)
116 m_spaceIndicatorSaves.init(L"",eControl_SpaceIndicator,0, (4LL *1024LL * 1024LL * 1024LL) );
117#endif
118 m_bUpdateSaveSize = false;
119
120 m_bAllLoaded = false;
121 m_bRetrievingSaveThumbnails = false;
122 m_bSaveThumbnailReady = false;
123 m_bExitScene=false;
124 m_pSaveDetails=NULL;
125 m_bSavesDisplayed=false;
126 m_saveDetails = NULL;
127 m_iSaveDetailsCount = 0;
128 m_iTexturePacksNotInstalled = 0;
129 m_bCopying = false;
130 m_bCopyingCancelled = false;
131
132#ifndef _XBOX_ONE
133 m_bSaveTransferCancelled=false;
134 m_bSaveTransferInProgress=false;
135#endif
136 m_eAction = eAction_None;
137
138 m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
139
140#ifdef _XBOX_ONE
141 // 4J-PB - in order to buy the skin packs & texture packs, we need the signed offer ids for them, which we get in the availability info
142 // we need to retrieve this info though, so do it here
143 app.AddDLCRequest(e_Marketplace_Content); // content is skin packs, texture packs and mash-up packs
144#endif
145
146
147 int iLB = -1;
148
149#ifdef _XBOX
150 XPARTY_USER_LIST partyList;
151
152 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1))
153 {
154 m_bInParty=true;
155 }
156 else
157 {
158 m_bInParty=false;
159 }
160#endif
161
162#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) || defined(_DURANGO)
163 // Always clear the saves when we enter this menu
164 StorageManager.ClearSavesInfo();
165#endif
166
167 // 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
168 if(app.StartInstallDLCProcess(m_iPad)==true || app.DLCInstallPending())
169 {
170 // 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
171 m_bIgnoreInput = true;
172 }
173 else
174 {
175 Initialise();
176 }
177
178#ifdef __PSVITA__
179 if(CGameNetworkManager::usingAdhocMode() && SQRNetworkManager_AdHoc_Vita::GetAdhocStatus())
180 {
181 g_NetworkManager.startAdhocMatching(); // create the client matching context and clear out the friends list
182 }
183
184#endif
185
186 UpdateGamesList();
187
188 g_NetworkManager.SetSessionsUpdatedCallback( &UpdateGamesListCallback, this );
189
190 m_initData= new JoinMenuInitData();
191
192 // 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.
193 MinecraftServer::resetFlags();
194
195 // 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.
196 if( !m_bIgnoreInput)
197 {
198 app.m_dlcManager.checkForCorruptDLCAndAlert();
199 }
200
201 // 4J-PB - Only Xbox will not have trial DLC patched into the game
202#ifdef _XBOX
203 // 4J-PB - there may be texture packs we don't have, so use the info from TMS for this
204
205 DLC_INFO *pDLCInfo=NULL;
206
207 // first pass - look to see if there are any that are not in the list
208 bool bTexturePackAlreadyListed;
209 bool bNeedToGetTPD=false;
210 Minecraft *pMinecraft = Minecraft::GetInstance();
211 int texturePacksCount = pMinecraft->skins->getTexturePackCount();
212
213 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
214 {
215 bTexturePackAlreadyListed=false;
216#if defined(__PS3__) || defined(__ORBIS__)
217 char *pchDLCName=app.GetDLCInfoTextures(i);
218 pDLCInfo=app.GetDLCInfo(pchDLCName);
219#else
220 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
221 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
222#endif
223 for(unsigned int i = 0; i < texturePacksCount; ++i)
224 {
225 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
226 if(pDLCInfo && pDLCInfo->iConfig==tp->getDLCParentPackId())
227 {
228 bTexturePackAlreadyListed=true;
229 }
230 }
231 if(bTexturePackAlreadyListed==false)
232 {
233 // some missing
234 bNeedToGetTPD=true;
235
236 m_iTexturePacksNotInstalled++;
237 }
238 }
239
240 if(bNeedToGetTPD==true)
241 {
242 // add a TMS request for them
243 app.DebugPrintf("+++ Adding TMSPP request for texture pack data\n");
244 app.AddTMSPPFileTypeRequest(e_DLC_TexturePackData);
245 m_iConfigA= new int [m_iTexturePacksNotInstalled];
246 m_iTexturePacksNotInstalled=0;
247
248 for(unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i)
249 {
250 bTexturePackAlreadyListed=false;
251#if defined(__PS3__) || defined(__ORBIS__)
252 char *pchDLCName=app.GetDLCInfoTextures(i);
253 pDLCInfo=app.GetDLCInfo(pchDLCName);
254#else
255 ULONGLONG ull=app.GetDLCInfoTexturesFullOffer(i);
256 pDLCInfo=app.GetDLCInfoForFullOfferID(ull);
257#endif
258 for(unsigned int i = 0; i < texturePacksCount; ++i)
259 {
260 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(i);
261 if(pDLCInfo->iConfig==tp->getDLCParentPackId())
262 {
263 bTexturePackAlreadyListed=true;
264 }
265 }
266 if(bTexturePackAlreadyListed==false)
267 {
268 m_iConfigA[m_iTexturePacksNotInstalled++]=pDLCInfo->iConfig;
269 }
270 }
271 }
272
273 addTimer(CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME);
274#endif
275
276#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
277 m_eSaveTransferState = eSaveTransfer_Idle;
278#endif
279}
280
281
282UIScene_LoadOrJoinMenu::~UIScene_LoadOrJoinMenu()
283{
284 g_NetworkManager.SetSessionsUpdatedCallback( NULL, NULL );
285 app.SetLiveLinkRequired( false );
286
287 delete m_currentSessions;
288 m_currentSessions = NULL;
289
290#if TO_BE_IMPLEMENTED
291 // Reset the background downloading, in case we changed it by attempting to download a texture pack
292 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
293#endif
294
295 if(m_saveDetails)
296 {
297 for(int i = 0; i < m_iSaveDetailsCount; ++i)
298 {
299 delete m_saveDetails[i].pbThumbnailData;
300 }
301 delete [] m_saveDetails;
302 }
303}
304
305void UIScene_LoadOrJoinMenu::updateTooltips()
306{
307#if defined __PS3__ || defined __ORBIS__ || defined __PSVITA__
308 if(m_eSaveTransferState!=eSaveTransfer_Idle)
309 {
310 // we're in a full screen progress for the save download here, so don't change the tooltips
311 return;
312 }
313#endif
314
315 // update the tooltips
316 // if the saves list has focus, then we should show the Delete Save tooltip
317 // if the games list has focus, then we should the the View Gamercard tooltip
318 int iRB=-1;
319 int iY = -1;
320 int iLB = -1;
321 int iX=-1;
322 if (DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0)
323 {
324 iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
325 }
326 else if (DoesSavesListHaveFocus())
327 {
328 if((m_iDefaultButtonsC > 0) && (m_iSaveListIndex >= m_iDefaultButtonsC))
329 {
330 if(StorageManager.GetSaveDisabled())
331 {
332 iRB=IDS_TOOLTIPS_DELETESAVE;
333 }
334 else
335 {
336 if(StorageManager.EnoughSpaceForAMinSaveGame())
337 {
338 iRB=IDS_TOOLTIPS_SAVEOPTIONS;
339 }
340 else
341 {
342 iRB=IDS_TOOLTIPS_DELETESAVE;
343 }
344 }
345 }
346 }
347 else if(DoesMashUpWorldHaveFocus())
348 {
349 // If it's a mash-up pack world, give the Hide option
350 iRB=IDS_TOOLTIPS_HIDE;
351 }
352
353 if(m_bInParty)
354 {
355 if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES;
356 else iLB = IDS_TOOLTIPS_PARTY_GAMES;
357 }
358
359#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
360 if(m_iPad == ProfileManager.GetPrimaryPad() ) iY = IDS_TOOLTIPS_GAME_INVITES;
361#endif
362
363 if(ProfileManager.IsFullVersion()==false )
364 {
365 iRB = -1;
366 }
367 else if(StorageManager.GetSaveDisabled())
368 {
369#ifdef _XBOX
370 iX = IDS_TOOLTIPS_SELECTDEVICE;
371#endif
372 }
373 else
374 {
375#if defined _XBOX_ONE
376 if(ProfileManager.IsSignedInLive( m_iPad ))
377 {
378 // Is there a save from 360 on TMS?
379 iX=IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD;
380 }
381#elif defined SONY_REMOTE_STORAGE_DOWNLOAD
382 // Is there a save from PS3 or PSVita available?
383 // Sony asked that this be displayed at all times so users are aware of the functionality. We'll display some text when there's no save available
384 //if(app.getRemoteStorage()->saveIsAvailable())
385 {
386 bool bSignedInLive = ProfileManager.IsSignedInLive(m_iPad);
387 if(bSignedInLive)
388 {
389 iX=IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD;
390 }
391 }
392#else
393 iX = IDS_TOOLTIPS_CHANGEDEVICE;
394#endif
395 }
396
397 ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, iX, iY,-1,-1,iLB,iRB);
398}
399
400//
401void UIScene_LoadOrJoinMenu::Initialise()
402{
403 m_iSaveListIndex = 0;
404 m_iGameListIndex = 0;
405
406 m_iDefaultButtonsC = 0;
407 m_iMashUpButtonsC=0;
408
409 // Check if we're in the trial version
410 if(ProfileManager.IsFullVersion()==false)
411 {
412
413
414 AddDefaultButtons();
415
416#if TO_BE_IMPLEMENTED
417 m_pSavesList->SetCurSelVisible(0);
418#endif
419 }
420 else if(StorageManager.GetSaveDisabled())
421 {
422#if defined(__PS3__) || defined(__ORBIS__) || defined (__PSVITA__)
423 GetSaveInfo();
424#else
425
426#if TO_BE_IMPLEMENTED
427 if(StorageManager.GetSaveDeviceSelected(m_iPad))
428#endif
429 {
430 // saving is disabled, but we should still be able to load from a selected save device
431
432
433
434 GetSaveInfo();
435 }
436#if TO_BE_IMPLEMENTED
437 else
438 {
439 AddDefaultButtons();
440 m_controlSavesTimer.setVisible( false );
441 }
442#endif
443#endif // __PS3__ || __ORBIS
444 }
445 else
446 {
447 // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename)
448 bool bCanRename = StorageManager.EnoughSpaceForAMinSaveGame();
449
450 GetSaveInfo();
451 }
452
453 m_bIgnoreInput=false;
454 app.m_dlcManager.checkForCorruptDLCAndAlert();
455}
456
457void UIScene_LoadOrJoinMenu::updateComponents()
458{
459 m_parentLayer->showComponent(m_iPad,eUIComponent_Panorama,true);
460 m_parentLayer->showComponent(m_iPad,eUIComponent_Logo,true);
461}
462
463void UIScene_LoadOrJoinMenu::handleDestroy()
464{
465#ifdef __PSVITA__
466 app.DebugPrintf("missing InputManager.DestroyKeyboard on Vita !!!!!!\n");
467#endif
468
469 // shut down the keyboard if it is displayed
470#if ( defined __PS3__ || defined __ORBIS__ || defined _DURANGO)
471 InputManager.DestroyKeyboard();
472#endif
473}
474
475void UIScene_LoadOrJoinMenu::handleGainFocus(bool navBack)
476{
477 UIScene::handleGainFocus(navBack);
478
479 updateTooltips();
480
481 // Add load online timer
482 addTimer(JOIN_LOAD_ONLINE_TIMER_ID,JOIN_LOAD_ONLINE_TIMER_TIME);
483
484 if(navBack)
485 {
486 app.SetLiveLinkRequired( true );
487
488 m_bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
489
490 // re-enable button presses
491 m_bIgnoreInput=false;
492
493 // 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
494 if(app.StartInstallDLCProcess(m_iPad)==false)
495 {
496 // not doing a mount, so re-enable input
497 m_bIgnoreInput=false;
498 }
499 else
500 {
501 m_bIgnoreInput=true;
502 m_buttonListSaves.clearList();
503 m_controlSavesTimer.setVisible(true);
504 }
505
506 if( m_bMultiplayerAllowed )
507 {
508#if TO_BE_IMPLEMENTED
509 HXUICLASS hClassFullscreenProgress = XuiFindClass( L"CScene_FullscreenProgress" );
510 HXUICLASS hClassConnectingProgress = XuiFindClass( L"CScene_ConnectingProgress" );
511
512 // If we are navigating back from a full screen progress scene, then that means a connection attempt failed
513 if( XuiIsInstanceOf( hSceneFrom, hClassFullscreenProgress ) || XuiIsInstanceOf( hSceneFrom, hClassConnectingProgress ) )
514 {
515 UpdateGamesList();
516 }
517#endif
518 }
519 else
520 {
521 m_buttonListGames.clearList();
522 m_controlJoinTimer.setVisible(true);
523 m_labelNoGames.setVisible(false);
524#if TO_BE_IMPLEMENTED
525 m_SavesList.InitFocus(m_iPad);
526#endif
527 }
528
529 // are we back here because of a delete of a corrupt save?
530
531 if(app.GetCorruptSaveDeleted())
532 {
533 // wipe the list and repopulate it
534 m_iState=e_SavesRepopulateAfterDelete;
535 app.SetCorruptSaveDeleted(false);
536 }
537 }
538}
539
540void UIScene_LoadOrJoinMenu::handleLoseFocus()
541{
542 // Kill load online timer
543 killTimer(JOIN_LOAD_ONLINE_TIMER_ID);
544}
545
546wstring UIScene_LoadOrJoinMenu::getMoviePath()
547{
548 return L"LoadOrJoinMenu";
549}
550
551void UIScene_LoadOrJoinMenu::tick()
552{
553 UIScene::tick();
554
555
556
557#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined _WINDOWS64 || defined __PSVITA__)
558 if(m_bExitScene) // navigate forward or back
559 {
560 if(!m_bRetrievingSaveThumbnails)
561 {
562 // need to wait for any callback retrieving thumbnail to complete
563 navigateBack();
564 }
565 }
566 // Stop loading thumbnails if we navigate forwards
567 if(hasFocus(m_iPad))
568 {
569#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
570 // if the loadOrJoin menu has focus again, we can clear the saveTransfer flag now. Added so we can delay the ehternet disconnect till it's cleaned up
571 if(m_eSaveTransferState == eSaveTransfer_Idle)
572 m_bSaveTransferRunning = false;
573#endif
574#if defined(_XBOX_ONE) || defined(__ORBIS__)
575 if(m_bUpdateSaveSize)
576 {
577 if((m_iDefaultButtonsC > 0) && (m_iSaveListIndex >= m_iDefaultButtonsC))
578 {
579 m_spaceIndicatorSaves.selectSave(m_iSaveListIndex-m_iDefaultButtonsC);
580 }
581 else
582 {
583 m_spaceIndicatorSaves.selectSave(-1);
584 }
585 m_bUpdateSaveSize = false;
586 }
587#endif
588 // Display the saves if we have them
589 if(!m_bSavesDisplayed)
590 {
591 m_pSaveDetails=StorageManager.ReturnSavesInfo();
592 if(m_pSaveDetails!=NULL)
593 {
594 //CD - Fix - Adding define for ORBIS/XBOXONE
595#if defined(_XBOX_ONE) || defined(__ORBIS__)
596 m_spaceIndicatorSaves.reset();
597#endif
598
599 AddDefaultButtons();
600 m_bSavesDisplayed=true;
601 UpdateGamesList();
602
603 if(m_saveDetails!=NULL)
604 {
605 for(unsigned int i = 0; i < m_iSaveDetailsCount; ++i)
606 {
607 if(m_saveDetails[i].pbThumbnailData!=NULL)
608 {
609 delete m_saveDetails[i].pbThumbnailData;
610 }
611 }
612 delete m_saveDetails;
613 }
614 m_saveDetails = new SaveListDetails[m_pSaveDetails->iSaveC];
615
616 m_iSaveDetailsCount = m_pSaveDetails->iSaveC;
617 for(unsigned int i = 0; i < m_pSaveDetails->iSaveC; ++i)
618 {
619#if defined(_XBOX_ONE)
620 m_spaceIndicatorSaves.addSave(m_pSaveDetails->SaveInfoA[i].totalSize);
621#elif defined(__ORBIS__)
622 m_spaceIndicatorSaves.addSave(m_pSaveDetails->SaveInfoA[i].blocksUsed * (32 * 1024) );
623#endif
624#ifdef _DURANGO
625 m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, L"");
626
627 m_saveDetails[i].saveId = i;
628 memcpy(m_saveDetails[i].UTF16SaveName, m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, 128);
629 memcpy(m_saveDetails[i].UTF16SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH);
630#else
631 m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, L"");
632
633 m_saveDetails[i].saveId = i;
634 memcpy(m_saveDetails[i].UTF8SaveName, m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, 128);
635 memcpy(m_saveDetails[i].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH);
636#endif
637 }
638 m_controlSavesTimer.setVisible( false );
639
640 // set focus on the first button
641
642 }
643 }
644
645 if(!m_bExitScene && m_bSavesDisplayed && !m_bRetrievingSaveThumbnails && !m_bAllLoaded)
646 {
647 if( m_iRequestingThumbnailId < (m_buttonListSaves.getItemCount() - m_iDefaultButtonsC ))
648 {
649 m_bRetrievingSaveThumbnails = true;
650 app.DebugPrintf("Requesting the first thumbnail\n");
651 // set the save to load
652 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
653 C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
654
655 if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
656 {
657 // something went wrong
658 m_bRetrievingSaveThumbnails=false;
659 m_bAllLoaded = true;
660 }
661 }
662 }
663 else if (m_bSavesDisplayed && m_bSaveThumbnailReady)
664 {
665 m_bSaveThumbnailReady = false;
666
667 // check we're not waiting to exit the scene
668 if(!m_bExitScene)
669 {
670 // convert to utf16
671 uint16_t u16Message[MAX_SAVEFILENAME_LENGTH];
672#ifdef _DURANGO
673 // Already utf16 on durango
674 memcpy(u16Message, m_saveDetails[m_iRequestingThumbnailId].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH);
675#elif defined(_WINDOWS64)
676 int result = ::MultiByteToWideChar(
677 CP_UTF8, // convert from UTF-8
678 MB_ERR_INVALID_CHARS, // error on invalid chars
679 m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename, // source UTF-8 string
680 MAX_SAVEFILENAME_LENGTH, // total length of source UTF-8 string,
681 // in CHAR's (= bytes), including end-of-string \0
682 (wchar_t *)u16Message, // destination buffer
683 MAX_SAVEFILENAME_LENGTH // size of destination buffer, in WCHAR's
684 );
685#else
686#ifdef __PS3
687 size_t srcmax,dstmax;
688#else
689 uint32_t srcmax,dstmax;
690 uint32_t srclen,dstlen;
691#endif
692 srcmax=MAX_SAVEFILENAME_LENGTH;
693 dstmax=MAX_SAVEFILENAME_LENGTH;
694
695#if defined(__PS3__)
696 L10nResult lres= UTF8stoUTF16s((uint8_t *)m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename,&srcmax,u16Message,&dstmax);
697#else
698 SceCesUcsContext context;
699 sceCesUcsContextInit(&context);
700
701 sceCesUtf8StrToUtf16Str(&context, (uint8_t *)m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename,srcmax,&srclen,u16Message,dstmax,&dstlen);
702#endif
703#endif
704 if( m_saveDetails[m_iRequestingThumbnailId].pbThumbnailData )
705 {
706 registerSubstitutionTexture((wchar_t *)u16Message,m_saveDetails[m_iRequestingThumbnailId].pbThumbnailData,m_saveDetails[m_iRequestingThumbnailId].dwThumbnailSize);
707 }
708 m_buttonListSaves.setTextureName(m_iRequestingThumbnailId + m_iDefaultButtonsC, (wchar_t *)u16Message);
709
710 ++m_iRequestingThumbnailId;
711 if( m_iRequestingThumbnailId < (m_buttonListSaves.getItemCount() - m_iDefaultButtonsC ))
712 {
713 app.DebugPrintf("Requesting another thumbnail\n");
714 // set the save to load
715 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
716 C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this);
717 if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail)
718 {
719 // something went wrong
720 m_bRetrievingSaveThumbnails=false;
721 m_bAllLoaded = true;
722 }
723 }
724 else
725 {
726 m_bRetrievingSaveThumbnails = false;
727 m_bAllLoaded = true;
728 }
729 }
730 else
731 {
732 // stop retrieving thumbnails, and exit
733 m_bRetrievingSaveThumbnails = false;
734 }
735 }
736 }
737
738 switch(m_iState)
739 {
740 case e_SavesIdle:
741 break;
742 case e_SavesRepopulate:
743 m_bIgnoreInput = false;
744 m_iState=e_SavesIdle;
745 m_bAllLoaded=false;
746 m_bRetrievingSaveThumbnails=false;
747 m_iRequestingThumbnailId = 0;
748 GetSaveInfo();
749 break;
750 case e_SavesRepopulateAfterMashupHide:
751 m_bIgnoreInput = false;
752 m_iRequestingThumbnailId = 0;
753 m_bAllLoaded=false;
754 m_bRetrievingSaveThumbnails=false;
755 m_bSavesDisplayed=false;
756 m_iSaveInfoC=0;
757 m_buttonListSaves.clearList();
758 GetSaveInfo();
759 m_iState=e_SavesIdle;
760 break;
761 case e_SavesRepopulateAfterDelete:
762 case e_SavesRepopulateAfterTransferDownload:
763 m_bIgnoreInput = false;
764 m_iRequestingThumbnailId = 0;
765 m_bAllLoaded=false;
766 m_bRetrievingSaveThumbnails=false;
767 m_bSavesDisplayed=false;
768 m_iSaveInfoC=0;
769 m_buttonListSaves.clearList();
770 StorageManager.ClearSavesInfo();
771 GetSaveInfo();
772 m_iState=e_SavesIdle;
773 break;
774 }
775#else
776 if(!m_bSavesDisplayed)
777 {
778 AddDefaultButtons();
779 m_bSavesDisplayed=true;
780 m_controlSavesTimer.setVisible( false );
781 }
782#endif
783
784#ifdef _XBOX_ONE
785 if(g_NetworkManager.ShouldMessageForFullSession())
786 {
787 UINT uiIDA[1];
788 uiIDA[0]=IDS_CONFIRM_OK;
789 ui.RequestErrorMessage( IDS_CONNECTION_FAILED, IDS_IN_PARTY_SESSION_FULL, uiIDA,1,ProfileManager.GetPrimaryPad());
790 }
791#endif
792
793 // SAVE TRANSFERS
794#ifdef __ORBIS__
795 // check the status of the PSPlus common dialog
796 switch (sceNpCommerceDialogUpdateStatus())
797 {
798 case SCE_COMMON_DIALOG_STATUS_FINISHED:
799 {
800 SceNpCommerceDialogResult Result;
801 sceNpCommerceDialogGetResult(&Result);
802 sceNpCommerceDialogTerminate();
803
804 if(Result.authorized)
805 {
806 // they just became a PSPlus member
807 ProfileManager.PsPlusUpdate(ProfileManager.GetPrimaryPad(), &Result);
808
809 }
810 else
811 {
812
813 }
814
815 // 4J-JEV: Fix for PS4 #5148 - [ONLINE] If the user attempts to join a game when they do not have Playstation Plus, the title will lose all functionality.
816 m_bIgnoreInput = false;
817 }
818 break;
819 default:
820 break;
821 }
822#endif
823
824}
825
826void UIScene_LoadOrJoinMenu::GetSaveInfo()
827{
828 unsigned int uiSaveC=0;
829
830 // This will return with the number retrieved in uiSaveC
831
832 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled())
833 {
834#ifdef __ORBIS__
835 // We need to make sure this is non-null so that we have an idea of free space
836 m_pSaveDetails=StorageManager.ReturnSavesInfo();
837 if(m_pSaveDetails==NULL)
838 {
839 C4JStorage::ESaveGameState eSGIStatus= StorageManager.GetSavesInfo(m_iPad,NULL,this,"save");
840 }
841#endif
842
843 uiSaveC = 0;
844#ifdef _XBOX
845 File savesDir(L"GAME:\\Saves");
846#else
847 File savesDir(L"Saves");
848#endif
849 if( savesDir.exists() )
850 {
851 m_saves = savesDir.listFiles();
852 uiSaveC = (unsigned int)m_saves->size();
853 }
854 // add the New Game and Tutorial after the saves list is retrieved, if there are any saves
855
856 // Add two for New Game and Tutorial
857 unsigned int listItems = uiSaveC;
858
859 AddDefaultButtons();
860
861 for(unsigned int i=0;i<listItems;i++)
862 {
863
864 wstring wName = m_saves->at(i)->getName();
865 wchar_t *name = new wchar_t[wName.size()+1];
866 for(unsigned int j = 0; j < wName.size(); ++j)
867 {
868 name[j] = wName[j];
869 }
870 name[wName.size()] = 0;
871 m_buttonListSaves.addItem(name,L"");
872 }
873 m_bSavesDisplayed = true;
874 m_bAllLoaded = true;
875 m_bIgnoreInput = false;
876 }
877 else
878 {
879 // clear the saves list
880 m_bSavesDisplayed = false; // we're blocking the exit from this scene until complete
881 m_buttonListSaves.clearList();
882 m_iSaveInfoC=0;
883 m_controlSavesTimer.setVisible(true);
884
885 m_pSaveDetails=StorageManager.ReturnSavesInfo();
886 if(m_pSaveDetails==NULL)
887 {
888 C4JStorage::ESaveGameState eSGIStatus= StorageManager.GetSavesInfo(m_iPad,NULL,this,"save");
889 }
890
891#if TO_BE_IMPLEMENTED
892 if(eSGIStatus==C4JStorage::ESGIStatus_NoSaves)
893 {
894 uiSaveC=0;
895 m_controlSavesTimer.setVisible( false );
896 m_SavesList.SetEnable(TRUE);
897 }
898#endif
899 }
900
901 return;
902}
903
904void UIScene_LoadOrJoinMenu::AddDefaultButtons()
905{
906 m_iDefaultButtonsC = 0;
907 m_iMashUpButtonsC=0;
908 m_generators.clear();
909
910 m_buttonListSaves.addItem(app.GetString(IDS_CREATE_NEW_WORLD));
911 m_iDefaultButtonsC++;
912
913 int i = 0;
914
915 for(AUTO_VAR(it, app.getLevelGenerators()->begin()); it != app.getLevelGenerators()->end(); ++it)
916 {
917 LevelGenerationOptions *levelGen = *it;
918
919 // retrieve the save icon from the texture pack, if there is one
920 unsigned int uiTexturePackID=levelGen->getRequiredTexturePackId();
921
922 if(uiTexturePackID!=0)
923 {
924 unsigned int uiMashUpWorldsBitmask=app.GetMashupPackWorlds(m_iPad);
925
926 if((uiMashUpWorldsBitmask & (1<<(uiTexturePackID-1024)))==0)
927 {
928 // this world is hidden, so skip
929 continue;
930 }
931 }
932
933 // 4J-JEV: For debug. Ignore worlds with no name.
934 LPCWSTR wstr = levelGen->getWorldName();
935 m_buttonListSaves.addItem( wstr );
936 m_generators.push_back(levelGen);
937
938 if(uiTexturePackID!=0)
939 {
940 // increment the count of the mash-up pack worlds in the save list
941 m_iMashUpButtonsC++;
942 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackById(levelGen->getRequiredTexturePackId());
943 DWORD dwImageBytes;
944 PBYTE pbImageData = tp->getPackIcon(dwImageBytes);
945
946 if(dwImageBytes > 0 && pbImageData)
947 {
948 wchar_t imageName[64];
949 swprintf(imageName,64,L"tpack%08x",tp->getId());
950 registerSubstitutionTexture(imageName, pbImageData, dwImageBytes);
951 m_buttonListSaves.setTextureName( m_buttonListSaves.getItemCount() - 1, imageName );
952 }
953 }
954
955 ++i;
956 }
957 m_iDefaultButtonsC += i;
958}
959
960void UIScene_LoadOrJoinMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
961{
962 if(m_bIgnoreInput) return;
963
964 // if we're retrieving save info, ignore key presses
965 if(!m_bSavesDisplayed) return;
966
967 ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released);
968
969 switch(key)
970 {
971 case ACTION_MENU_CANCEL:
972 if(pressed)
973 {
974#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
975 m_bExitScene=true;
976#else
977 navigateBack();
978#endif
979 handled = true;
980 }
981 break;
982 case ACTION_MENU_X:
983#if TO_BE_IMPLEMENTED
984 // Change device
985 // Fix for #12531 - TCR 001: BAS Game Stability: When a player selects to change a storage
986 // device, and repeatedly backs out of the SD screen, disconnects from LIVE, and then selects a SD, the title crashes.
987 m_bIgnoreInput=true;
988 StorageManager.SetSaveDevice(&CScene_MultiGameJoinLoad::DeviceSelectReturned,this,true);
989 ui.PlayUISFX(eSFX_Press);
990#endif
991 // Save Transfer
992#ifdef _XBOX_ONE
993 if(ProfileManager.IsSignedInLive( m_iPad ))
994 {
995 UIScene_LoadOrJoinMenu::s_ulFileSize=0;
996 LaunchSaveTransfer();
997 }
998#endif
999#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
1000 {
1001 bool bSignedInLive = ProfileManager.IsSignedInLive(iPad);
1002 if(bSignedInLive)
1003 {
1004 LaunchSaveTransfer();
1005 }
1006 }
1007#endif
1008 break;
1009 case ACTION_MENU_Y:
1010#if defined(__PS3__) || defined(__PSVITA__) || defined(__ORBIS__)
1011 m_eAction = eAction_ViewInvites;
1012 if(pressed && iPad == ProfileManager.GetPrimaryPad())
1013 {
1014#ifdef __ORBIS__
1015 // Check if PSN is unavailable because of age restriction
1016 int npAvailability = ProfileManager.getNPAvailability(iPad);
1017 if (npAvailability == SCE_NP_ERROR_AGE_RESTRICTION)
1018 {
1019 UINT uiIDA[1];
1020 uiIDA[0] = IDS_OK;
1021 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPad);
1022
1023 break;
1024 }
1025#endif
1026
1027 // are we offline?
1028 if(!ProfileManager.IsSignedInLive(iPad))
1029 {
1030 // get them to sign in to online
1031 UINT uiIDA[2];
1032 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT;
1033 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE;
1034 ui.RequestAlertMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(), &UIScene_LoadOrJoinMenu::MustSignInReturnedPSN, this);
1035 }
1036 else
1037 {
1038#ifdef __ORBIS__
1039 SQRNetworkManager_Orbis::RecvInviteGUI();
1040#elif defined __PSVITA__
1041 SQRNetworkManager_Vita::RecvInviteGUI();
1042#else
1043 int ret = sceNpBasicRecvMessageCustom(SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE, SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_INCLUDE_BOOTABLE, SYS_MEMORY_CONTAINER_ID_INVALID);
1044 app.DebugPrintf("sceNpBasicRecvMessageCustom return %d ( %08x )\n", ret, ret);
1045#endif
1046 }
1047 }
1048#elif defined(_DURANGO)
1049 if(getControlFocus() == eControl_GamesList && m_buttonListGames.getItemCount() > 0)
1050 {
1051 DWORD nIndex = m_buttonListGames.getCurrentSelection();
1052 FriendSessionInfo *pSelectedSession = m_currentSessions->at( nIndex );
1053
1054 PlayerUID uid = pSelectedSession->searchResult.m_playerXuids[0];
1055 if( uid != INVALID_XUID ) ProfileManager.ShowProfileCard(ProfileManager.GetLockedProfile(),uid);
1056 ui.PlayUISFX(eSFX_Press);
1057 }
1058#endif // __PS3__ || __ORBIS__
1059 break;
1060
1061 case ACTION_MENU_RIGHT_SCROLL:
1062 if(DoesSavesListHaveFocus())
1063 {
1064 // 4J-PB - check we are on a valid save
1065 if((m_iDefaultButtonsC != 0) && (m_iSaveListIndex >= m_iDefaultButtonsC))
1066 {
1067 m_bIgnoreInput = true;
1068
1069 // Could be delete save or Save Options
1070 if(StorageManager.GetSaveDisabled())
1071 {
1072 // delete the save game
1073 // Have to ask the player if they are sure they want to delete this game
1074 UINT uiIDA[2];
1075 uiIDA[0]=IDS_CONFIRM_CANCEL;
1076 uiIDA[1]=IDS_CONFIRM_OK;
1077 ui.RequestAlertMessage(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, iPad,&UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned,this);
1078 }
1079 else
1080 {
1081 if(StorageManager.EnoughSpaceForAMinSaveGame())
1082 {
1083 UINT uiIDA[4];
1084 uiIDA[0]=IDS_CONFIRM_CANCEL;
1085 uiIDA[1]=IDS_TITLE_RENAMESAVE;
1086 uiIDA[2]=IDS_TOOLTIPS_DELETESAVE;
1087 int numOptions = 3;
1088#ifdef SONY_REMOTE_STORAGE_UPLOAD
1089 if(ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()))
1090 {
1091 numOptions = 4;
1092 uiIDA[3]=IDS_TOOLTIPS_SAVETRANSFER_UPLOAD;
1093 }
1094#endif
1095#if defined _XBOX_ONE || defined __ORBIS__
1096 numOptions = 4;
1097 uiIDA[3]=IDS_COPYSAVE;
1098#endif
1099 ui.RequestAlertMessage(IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS, uiIDA, numOptions, iPad,&UIScene_LoadOrJoinMenu::SaveOptionsDialogReturned,this);
1100 }
1101 else
1102 {
1103 // delete the save game
1104 // Have to ask the player if they are sure they want to delete this game
1105 UINT uiIDA[2];
1106 uiIDA[0]=IDS_CONFIRM_CANCEL;
1107 uiIDA[1]=IDS_CONFIRM_OK;
1108 ui.RequestAlertMessage(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2,iPad,&UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned,this);
1109 }
1110 }
1111 ui.PlayUISFX(eSFX_Press);
1112 }
1113 }
1114 else if(DoesMashUpWorldHaveFocus())
1115 {
1116 // hiding a mash-up world
1117 if((m_iSaveListIndex != JOIN_LOAD_CREATE_BUTTON_INDEX))
1118 {
1119 LevelGenerationOptions *levelGen = m_generators.at(m_iSaveListIndex - 1);
1120
1121 if(!levelGen->isTutorial())
1122 {
1123 if(levelGen->requiresTexturePack())
1124 {
1125 unsigned int uiPackID=levelGen->getRequiredTexturePackId();
1126
1127 m_bIgnoreInput = true;
1128 app.HideMashupPackWorld(m_iPad,uiPackID);
1129
1130 // update the saves list
1131 m_iState = e_SavesRepopulateAfterMashupHide;
1132 }
1133 }
1134 }
1135 ui.PlayUISFX(eSFX_Press);
1136
1137 }
1138 break;
1139 case ACTION_MENU_LEFT_SCROLL:
1140#ifdef _XBOX
1141 if( m_bInParty )
1142 {
1143 m_bShowingPartyGamesOnly = !m_bShowingPartyGamesOnly;
1144 UpdateGamesList();
1145 CXuiSceneBase::PlayUISFX(eSFX_Press);
1146 }
1147#endif
1148 break;
1149 case ACTION_MENU_LEFT:
1150 case ACTION_MENU_RIGHT:
1151 {
1152 // if we are on the saves menu, check there are games in the games list to move to
1153 if(DoesSavesListHaveFocus())
1154 {
1155 if( m_buttonListGames.getItemCount() > 0)
1156 {
1157 sendInputToMovie(key, repeat, pressed, released);
1158 }
1159 }
1160 else
1161 {
1162 sendInputToMovie(key, repeat, pressed, released);
1163 }
1164 }
1165 break;
1166
1167 case ACTION_MENU_OK:
1168#ifdef __ORBIS__
1169 case ACTION_MENU_TOUCHPAD_PRESS:
1170#endif
1171 case ACTION_MENU_UP:
1172 case ACTION_MENU_DOWN:
1173 case ACTION_MENU_PAGEUP:
1174 case ACTION_MENU_PAGEDOWN:
1175 sendInputToMovie(key, repeat, pressed, released);
1176 handled = true;
1177 break;
1178 }
1179}
1180
1181int UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback(LPVOID lpParam,bool bRes)
1182{
1183 // 4J HEG - No reason to set value if keyboard was cancelled
1184 UIScene_LoadOrJoinMenu *pClass=(UIScene_LoadOrJoinMenu *)lpParam;
1185 pClass->m_bIgnoreInput=false;
1186 if (bRes)
1187 {
1188 uint16_t ui16Text[128];
1189 ZeroMemory(ui16Text, 128 * sizeof(uint16_t) );
1190 InputManager.GetText(ui16Text);
1191
1192 // check the name is valid
1193 if(ui16Text[0]!=0)
1194 {
1195#if (defined __PS3__ || defined __ORBIS__ || defined _DURANGO || defined(__PSVITA__))
1196 // open the save and overwrite the metadata
1197 StorageManager.RenameSaveData(pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC, ui16Text,&UIScene_LoadOrJoinMenu::RenameSaveDataReturned,pClass);
1198#endif
1199 }
1200 else
1201 {
1202 pClass->m_bIgnoreInput=false;
1203 pClass->updateTooltips();
1204 }
1205 }
1206 else
1207 {
1208 pClass->m_bIgnoreInput=false;
1209 pClass->updateTooltips();
1210 }
1211
1212
1213 return 0;
1214}
1215void UIScene_LoadOrJoinMenu::handleInitFocus(F64 controlId, F64 childId)
1216{
1217 app.DebugPrintf(app.USER_SR, "UIScene_LoadOrJoinMenu::handleInitFocus - %d , %d\n", (int)controlId, (int)childId);
1218}
1219
1220void UIScene_LoadOrJoinMenu::handleFocusChange(F64 controlId, F64 childId)
1221{
1222 app.DebugPrintf(app.USER_SR, "UIScene_LoadOrJoinMenu::handleFocusChange - %d , %d\n", (int)controlId, (int)childId);
1223
1224 switch((int)controlId)
1225 {
1226 case eControl_GamesList:
1227 m_iGameListIndex = childId;
1228 m_buttonListGames.updateChildFocus( (int) childId );
1229 break;
1230 case eControl_SavesList:
1231 m_iSaveListIndex = childId;
1232 m_bUpdateSaveSize = true;
1233 break;
1234 };
1235 updateTooltips();
1236}
1237
1238
1239#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
1240void UIScene_LoadOrJoinMenu::remoteStorageGetSaveCallback(LPVOID lpParam, SonyRemoteStorage::Status s, int error_code)
1241{
1242 app.DebugPrintf("remoteStorageGetCallback err : 0x%08x\n", error_code);
1243 assert(error_code == 0);
1244 ((UIScene_LoadOrJoinMenu*)lpParam)->LoadSaveFromCloud();
1245}
1246#endif
1247
1248void UIScene_LoadOrJoinMenu::handlePress(F64 controlId, F64 childId)
1249{
1250 switch((int)controlId)
1251 {
1252 case eControl_SavesList:
1253 {
1254 m_bIgnoreInput=true;
1255
1256 int lGenID = (int)childId - 1;
1257
1258 //CD - Added for audio
1259 ui.PlayUISFX(eSFX_Press);
1260
1261 if((int)childId == JOIN_LOAD_CREATE_BUTTON_INDEX)
1262 {
1263 app.SetTutorialMode( false );
1264
1265 m_controlJoinTimer.setVisible( false );
1266
1267 app.SetCorruptSaveDeleted(false);
1268
1269 CreateWorldMenuInitData *params = new CreateWorldMenuInitData();
1270 params->iPad = m_iPad;
1271 ui.NavigateToScene(m_iPad,eUIScene_CreateWorldMenu,(void *)params);
1272 }
1273 else if (lGenID < m_generators.size())
1274 {
1275 LevelGenerationOptions *levelGen = m_generators.at(lGenID);
1276 app.SetTutorialMode( levelGen->isTutorial() );
1277 // Reset the autosave time
1278 app.SetAutosaveTimerTime();
1279
1280 if(levelGen->isTutorial())
1281 {
1282 LoadLevelGen(levelGen);
1283 }
1284 else
1285 {
1286 LoadMenuInitData *params = new LoadMenuInitData();
1287 params->iPad = m_iPad;
1288 // 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
1289 params->iSaveGameInfoIndex=-1;
1290 //params->pbSaveRenamed=&m_bSaveRenamed;
1291 params->levelGen = levelGen;
1292 params->saveDetails = NULL;
1293
1294 // navigate to the settings scene
1295 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_LoadMenu, params);
1296 }
1297 }
1298 else
1299 {
1300#ifdef __ORBIS__
1301 // check if this is a damaged save
1302 PSAVE_INFO pSaveInfo = &m_pSaveDetails->SaveInfoA[((int)childId)-m_iDefaultButtonsC];
1303 if(pSaveInfo->thumbnailData == NULL && pSaveInfo->modifiedTime == 0) // no thumbnail data and time of zero and zero blocks useset for corrupt files
1304 {
1305 // give the option to delete the save
1306 UINT uiIDA[2];
1307 uiIDA[0]=IDS_CONFIRM_CANCEL;
1308 uiIDA[1]=IDS_CONFIRM_OK;
1309 ui.RequestAlertMessage(IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE, IDS_CORRUPT_OR_DAMAGED_SAVE_TEXT, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned,this);
1310
1311 }
1312 else
1313#endif
1314 {
1315 app.SetTutorialMode( false );
1316
1317 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled())
1318 {
1319 LoadSaveFromDisk(m_saves->at((int)childId-m_iDefaultButtonsC));
1320 }
1321 else
1322 {
1323 LoadMenuInitData *params = new LoadMenuInitData();
1324 params->iPad = m_iPad;
1325 // 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
1326 params->iSaveGameInfoIndex=((int)childId)-m_iDefaultButtonsC;
1327 //params->pbSaveRenamed=&m_bSaveRenamed;
1328 params->levelGen = NULL;
1329 params->saveDetails = &m_saveDetails[ ((int)childId)-m_iDefaultButtonsC ];
1330
1331#ifdef _XBOX_ONE
1332 // On XB1, saves might need syncing, in which case inform the user so they can decide whether they want to wait for this to happen
1333 if( m_pSaveDetails->SaveInfoA[params->iSaveGameInfoIndex].needsSync )
1334 {
1335 unsigned int uiIDA[2];
1336 uiIDA[0]=IDS_CONFIRM_SYNC;
1337 uiIDA[1]=IDS_CONFIRM_CANCEL;
1338
1339 m_loadMenuInitData = params;
1340 ui.RequestAlertMessage(IDS_LOAD_SAVED_WORLD, IDS_CONFIRM_SYNC_REQUIRED, uiIDA, 2, ProfileManager.GetPrimaryPad(),&NeedSyncMessageReturned,this);
1341 }
1342 else
1343#endif
1344 {
1345 // navigate to the settings scene
1346 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_LoadMenu, params);
1347 }
1348 }
1349 }
1350 }
1351 }
1352 break;
1353 case eControl_GamesList:
1354 {
1355 m_bIgnoreInput=true;
1356
1357 m_eAction = eAction_JoinGame;
1358
1359 //CD - Added for audio
1360 ui.PlayUISFX(eSFX_Press);
1361
1362 {
1363 int nIndex = (int)childId;
1364 m_iGameListIndex = nIndex;
1365 CheckAndJoinGame(nIndex);
1366 }
1367
1368 break;
1369 }
1370 }
1371}
1372
1373void UIScene_LoadOrJoinMenu::CheckAndJoinGame(int gameIndex)
1374{
1375 if( m_buttonListGames.getItemCount() > 0 && gameIndex < m_currentSessions->size() )
1376 {
1377#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
1378 // 4J-PB - is the player allowed to join games?
1379 bool noUGC=false;
1380 bool bContentRestricted=false;
1381
1382 // we're online, since we are joining a game
1383 ProfileManager.GetChatAndContentRestrictions(m_iPad,true,&noUGC,&bContentRestricted,NULL);
1384
1385#ifdef __ORBIS__
1386 // 4J Stu - On PS4 we don't restrict playing multiplayer based on chat restriction, so remove this check
1387 noUGC = false;
1388
1389 bool bPlayStationPlus=true;
1390 int iPadWithNoPlaystationPlus=0;
1391 bool isSignedInLive = true;
1392 int iPadNotSignedInLive = -1;
1393 for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i)
1394 {
1395 if( InputManager.IsPadConnected(i) || ProfileManager.IsSignedIn(i) )
1396 {
1397 if (isSignedInLive && !ProfileManager.IsSignedInLive(i))
1398 {
1399 // Record the first non signed in live pad
1400 iPadNotSignedInLive = i;
1401 }
1402
1403 isSignedInLive = isSignedInLive && ProfileManager.IsSignedInLive(i);
1404 if(ProfileManager.HasPlayStationPlus(i)==false)
1405 {
1406 bPlayStationPlus=false;
1407 break;
1408 }
1409 }
1410 }
1411#endif
1412#ifdef __PSVITA__
1413 if( CGameNetworkManager::usingAdhocMode() )
1414 {
1415 bContentRestricted = false;
1416 noUGC = false;
1417 }
1418#endif
1419
1420 if(noUGC)
1421 {
1422 // not allowed to join
1423#ifndef __PSVITA__
1424 UINT uiIDA[1];
1425 uiIDA[0]=IDS_CONFIRM_OK;
1426 // Not allowed to play online
1427 ui.RequestAlertMessage(IDS_ONLINE_GAME, IDS_CHAT_RESTRICTION_UGC, uiIDA, 1, m_iPad,NULL,this);
1428#else
1429 // Not allowed to play online
1430 ProfileManager.ShowSystemMessage( SCE_MSG_DIALOG_SYSMSG_TYPE_TRC_PSN_CHAT_RESTRICTION, 0 );
1431#endif
1432
1433 m_bIgnoreInput=false;
1434 return;
1435 }
1436 else if(bContentRestricted)
1437 {
1438 ui.RequestContentRestrictedMessageBox();
1439
1440 m_bIgnoreInput=false;
1441 return;
1442 }
1443#ifdef __ORBIS__
1444 // If this is an online game but not all players are signed in to Live, stop!
1445 else if (!isSignedInLive)
1446 {
1447 UINT uiIDA[1];
1448 uiIDA[0]=IDS_CONFIRM_OK;
1449
1450 // Check if PSN is unavailable because of age restriction
1451 int npAvailability = ProfileManager.getNPAvailability(iPadNotSignedInLive);
1452 if (npAvailability == SCE_NP_ERROR_AGE_RESTRICTION)
1453 {
1454 m_bIgnoreInput = false;
1455 // 4J Stu - This is a bit messy and is due to the library incorrectly returning false for IsSignedInLive if the npAvailability isn't SCE_OK
1456 ui.RequestErrorMessage(IDS_ONLINE_SERVICE_TITLE, IDS_CONTENT_RESTRICTION, uiIDA, 1, iPadNotSignedInLive);
1457 }
1458 else
1459 {
1460 ui.RequestErrorMessage( IDS_PRO_NOTONLINE_TITLE, IDS_PRO_NOTONLINE_TEXT, uiIDA,1,iPadNotSignedInLive, &UIScene_LoadOrJoinMenu::MustSignInReturnedPSN, this);
1461 }
1462 return;
1463 }
1464 else if(bPlayStationPlus==false)
1465 {
1466
1467 if(ProfileManager.RequestingPlaystationPlus(iPadWithNoPlaystationPlus))
1468 {
1469 // MGH - added this so we don't try and upsell when we don't know if the player has PS Plus yet (if it can't connect to the PS Plus server).
1470 UINT uiIDA[1];
1471 uiIDA[0]=IDS_OK;
1472 ui.RequestAlertMessage(IDS_ERROR_NETWORK_TITLE, IDS_ERROR_NETWORK, uiIDA, 1, ProfileManager.GetPrimaryPad(), NULL, NULL);
1473 return;
1474 }
1475
1476 // PS Plus upsell
1477 // 4J-PB - we're not allowed to show the text Playstation Plus - have to call the upsell all the time!
1478 // upsell psplus
1479 int32_t iResult=sceNpCommerceDialogInitialize();
1480
1481 SceNpCommerceDialogParam param;
1482 sceNpCommerceDialogParamInitialize(¶m);
1483 param.mode=SCE_NP_COMMERCE_DIALOG_MODE_PLUS;
1484 param.features = SCE_NP_PLUS_FEATURE_REALTIME_MULTIPLAY;
1485 param.userId = ProfileManager.getUserID(iPadWithNoPlaystationPlus);
1486
1487 iResult=sceNpCommerceDialogOpen(¶m);
1488
1489 // UINT uiIDA[2];
1490 // uiIDA[0]=IDS_CONFIRM_OK;
1491 // uiIDA[1]=IDS_PLAYSTATIONPLUS_SIGNUP;
1492 // ui.RequestMessageBox( IDS_FAILED_TO_CREATE_GAME_TITLE, IDS_NO_PLAYSTATIONPLUS, uiIDA,2,ProfileManager.GetPrimaryPad(),&UIScene_LoadOrJoinMenu::PSPlusReturned,this, app.GetStringTable(),NULL,0,false);
1493
1494 m_bIgnoreInput=false;
1495 return;
1496 }
1497
1498#endif
1499#endif
1500
1501 //CScene_MultiGameInfo::JoinMenuInitData *initData = new CScene_MultiGameInfo::JoinMenuInitData();
1502 m_initData->iPad = 0;;
1503 m_initData->selectedSession = m_currentSessions->at( gameIndex );
1504
1505 // check that we have the texture pack available
1506 // If it's not the default texture pack
1507 if(m_initData->selectedSession->data.texturePackParentId!=0)
1508 {
1509 int texturePacksCount = Minecraft::GetInstance()->skins->getTexturePackCount();
1510 bool bHasTexturePackInstalled=false;
1511
1512 for(int i=0;i<texturePacksCount;i++)
1513 {
1514 TexturePack *tp = Minecraft::GetInstance()->skins->getTexturePackByIndex(i);
1515 if(tp->getDLCParentPackId()==m_initData->selectedSession->data.texturePackParentId)
1516 {
1517 bHasTexturePackInstalled=true;
1518 break;
1519 }
1520 }
1521
1522 if(bHasTexturePackInstalled==false)
1523 {
1524 // upsell the texture pack
1525 // tell sentient about the upsell of the full version of the skin pack
1526#ifdef _XBOX
1527 ULONGLONG ullOfferID_Full;
1528 app.GetDLCFullOfferIDForPackID(m_initData->selectedSession->data.texturePackParentId,&ullOfferID_Full);
1529
1530 TelemetryManager->RecordUpsellPresented(m_iPad, eSet_UpsellID_Texture_DLC, ullOfferID_Full & 0xFFFFFFFF);
1531#endif
1532 UINT uiIDA[2];
1533
1534 uiIDA[0]=IDS_TEXTUREPACK_FULLVERSION;
1535 //uiIDA[1]=IDS_TEXTURE_PACK_TRIALVERSION;
1536 uiIDA[1]=IDS_CONFIRM_CANCEL;
1537
1538
1539 // Give the player a warning about the texture pack missing
1540 ui.RequestAlertMessage(IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE, IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2, m_iPad,&UIScene_LoadOrJoinMenu::TexturePackDialogReturned,this);
1541
1542 return;
1543 }
1544
1545#ifdef __PSVITA__
1546 if(CGameNetworkManager::usingAdhocMode() && !SQRNetworkManager_AdHoc_Vita::GetAdhocStatus())
1547 {
1548 // not connected to adhoc anymore, must have connected back to PSN to buy texture pack so sign in again
1549 SQRNetworkManager_AdHoc_Vita::AttemptAdhocSignIn(&UIScene_LoadOrJoinMenu::SignInAdhocReturned, this);
1550 return;
1551 }
1552#endif
1553 }
1554 m_controlJoinTimer.setVisible( false );
1555
1556#ifdef _XBOX
1557 // Reset the background downloading, in case we changed it by attempting to download a texture pack
1558 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
1559#endif
1560
1561 m_bIgnoreInput=true;
1562 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_JoinMenu,m_initData);
1563 }
1564}
1565
1566void UIScene_LoadOrJoinMenu::LoadLevelGen(LevelGenerationOptions *levelGen)
1567{
1568 // Load data from disc
1569 //File saveFile( L"Tutorial\\Tutorial" );
1570 //LoadSaveFromDisk(&saveFile);
1571
1572 // clear out the app's terrain features list
1573 app.ClearTerrainFeaturePosition();
1574
1575 StorageManager.ResetSaveData();
1576 // Make our next save default to the name of the level
1577 StorageManager.SetSaveTitle(levelGen->getDefaultSaveName().c_str());
1578
1579 bool isClientSide = false;
1580 bool isPrivate = false;
1581 // TODO int maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
1582 int maxPlayers = 8;
1583
1584 if( app.GetTutorialMode() )
1585 {
1586 isClientSide = false;
1587 maxPlayers = 4;
1588 }
1589
1590 g_NetworkManager.HostGame(0,isClientSide,isPrivate,maxPlayers,0);
1591
1592 NetworkGameInitData *param = new NetworkGameInitData();
1593 param->seed = 0;
1594 param->saveData = NULL;
1595 param->settings = app.GetGameHostOption( eGameHostOption_Tutorial );
1596 param->levelGen = levelGen;
1597
1598 if(levelGen->requiresTexturePack())
1599 {
1600 param->texturePackId = levelGen->getRequiredTexturePackId();
1601
1602 Minecraft *pMinecraft = Minecraft::GetInstance();
1603 pMinecraft->skins->selectTexturePackById(param->texturePackId);
1604 //pMinecraft->skins->updateUI();
1605 }
1606
1607#ifndef _XBOX
1608 g_NetworkManager.FakeLocalPlayerJoined();
1609#endif
1610
1611 LoadingInputParams *loadingParams = new LoadingInputParams();
1612 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
1613 loadingParams->lpParam = (LPVOID)param;
1614
1615 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
1616 completionData->bShowBackground=TRUE;
1617 completionData->bShowLogo=TRUE;
1618 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
1619 completionData->iPad = DEFAULT_XUI_MENU_USER;
1620 loadingParams->completionData = completionData;
1621
1622 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams);
1623}
1624
1625void UIScene_LoadOrJoinMenu::UpdateGamesListCallback(LPVOID pParam)
1626{
1627 if(pParam != NULL)
1628 {
1629 UIScene_LoadOrJoinMenu *pScene = (UIScene_LoadOrJoinMenu *)pParam;
1630 pScene->UpdateGamesList();
1631 }
1632}
1633
1634void UIScene_LoadOrJoinMenu::UpdateGamesList()
1635{
1636 // If we're ignoring input scene isn't active so do nothing
1637 if (m_bIgnoreInput) return;
1638
1639 // If a texture pack is loading, or will be loading, then ignore this ( we are going to be destroyed anyway)
1640 if( Minecraft::GetInstance()->skins->getSelected()->isLoadingData() || (Minecraft::GetInstance()->skins->needsUIUpdate() || ui.IsReloadingSkin()) ) return;
1641
1642 // if we're retrieving save info, don't show the list yet as we will be ignoring press events
1643 if(!m_bSavesDisplayed)
1644 {
1645 return;
1646 }
1647
1648
1649 FriendSessionInfo *pSelectedSession = NULL;
1650 if(DoesGamesListHaveFocus() && m_buttonListGames.getItemCount() > 0)
1651 {
1652 unsigned int nIndex = m_buttonListGames.getCurrentSelection();
1653 pSelectedSession = m_currentSessions->at( nIndex );
1654 }
1655
1656 SessionID selectedSessionId;
1657 ZeroMemory(&selectedSessionId,sizeof(SessionID));
1658 if( pSelectedSession != NULL )selectedSessionId = pSelectedSession->sessionId;
1659 pSelectedSession = NULL;
1660
1661 m_controlJoinTimer.setVisible( false );
1662
1663 // if the saves list has focus, then we should show the Delete Save tooltip
1664 // if the games list has focus, then we should show the View Gamercard tooltip
1665 int iRB=-1;
1666 int iY = -1;
1667 int iX=-1;
1668
1669 delete m_currentSessions;
1670 m_currentSessions = g_NetworkManager.GetSessionList( m_iPad, 1, m_bShowingPartyGamesOnly );
1671
1672 // Update the xui list displayed
1673 unsigned int xuiListSize = m_buttonListGames.getItemCount();
1674 unsigned int filteredListSize = (unsigned int)m_currentSessions->size();
1675
1676 BOOL gamesListHasFocus = DoesGamesListHaveFocus();
1677
1678 if(filteredListSize > 0)
1679 {
1680#if TO_BE_IMPLEMENTED
1681 if( !m_pGamesList->IsEnabled() )
1682 {
1683 m_pGamesList->SetEnable(TRUE);
1684 m_pGamesList->SetCurSel( 0 );
1685 }
1686#endif
1687 m_labelNoGames.setVisible( false );
1688 m_controlJoinTimer.setVisible( false );
1689 }
1690 else
1691 {
1692#if TO_BE_IMPLEMENTED
1693 m_pGamesList->SetEnable(FALSE);
1694#endif
1695 m_controlJoinTimer.setVisible( false );
1696 m_labelNoGames.setVisible( true );
1697
1698#if TO_BE_IMPLEMENTED
1699 if( gamesListHasFocus ) m_pGamesList->InitFocus(m_iPad);
1700#endif
1701 }
1702
1703 // clear out the games list and re-fill
1704 m_buttonListGames.clearList();
1705
1706 if( filteredListSize > 0 )
1707 {
1708 // Reset the focus to the selected session if it still exists
1709 unsigned int sessionIndex = 0;
1710 m_buttonListGames.setCurrentSelection(0);
1711
1712 for( AUTO_VAR(it, m_currentSessions->begin()); it < m_currentSessions->end(); ++it)
1713 {
1714 FriendSessionInfo *sessionInfo = *it;
1715
1716 wchar_t textureName[64] = L"\0";
1717
1718 // Is this a default game or a texture pack game?
1719 if(sessionInfo->data.texturePackParentId!=0)
1720 {
1721 // Do we have the texture pack
1722 Minecraft *pMinecraft = Minecraft::GetInstance();
1723 TexturePack *tp = pMinecraft->skins->getTexturePackById(sessionInfo->data.texturePackParentId);
1724 HRESULT hr;
1725
1726 DWORD dwImageBytes=0;
1727 PBYTE pbImageData=NULL;
1728
1729 if(tp==NULL)
1730 {
1731 DWORD dwBytes=0;
1732 PBYTE pbData=NULL;
1733 app.GetTPD(sessionInfo->data.texturePackParentId,&pbData,&dwBytes);
1734
1735 // is it in the tpd data ?
1736 app.GetFileFromTPD(eTPDFileType_Icon,pbData,dwBytes,&pbImageData,&dwImageBytes );
1737 if(dwImageBytes > 0 && pbImageData)
1738 {
1739 swprintf(textureName,64,L"%ls",sessionInfo->displayLabel);
1740 registerSubstitutionTexture(textureName,pbImageData,dwImageBytes);
1741 }
1742 }
1743 else
1744 {
1745 pbImageData = tp->getPackIcon(dwImageBytes);
1746 if(dwImageBytes > 0 && pbImageData)
1747 {
1748 swprintf(textureName,64,L"%ls",sessionInfo->displayLabel);
1749 registerSubstitutionTexture(textureName,pbImageData,dwImageBytes);
1750 }
1751 }
1752 }
1753 else
1754 {
1755 // default texture pack
1756 Minecraft *pMinecraft = Minecraft::GetInstance();
1757 TexturePack *tp = pMinecraft->skins->getTexturePackByIndex(0);
1758
1759 DWORD dwImageBytes;
1760 PBYTE pbImageData = tp->getPackIcon(dwImageBytes);
1761
1762 if(dwImageBytes > 0 && pbImageData)
1763 {
1764 swprintf(textureName,64,L"%ls",sessionInfo->displayLabel);
1765 registerSubstitutionTexture(textureName,pbImageData,dwImageBytes);
1766 }
1767 }
1768
1769 m_buttonListGames.addItem( sessionInfo->displayLabel, textureName );
1770
1771 if(memcmp( &selectedSessionId, &sessionInfo->sessionId, sizeof(SessionID) ) == 0)
1772 {
1773 m_buttonListGames.setCurrentSelection(sessionIndex);
1774 break;
1775 }
1776 ++sessionIndex;
1777 }
1778 }
1779
1780 updateTooltips();
1781}
1782
1783void UIScene_LoadOrJoinMenu::HandleDLCMountingComplete()
1784{
1785 Initialise();
1786}
1787
1788bool UIScene_LoadOrJoinMenu::DoesSavesListHaveFocus()
1789{
1790 if( m_buttonListSaves.hasFocus() )
1791 {
1792 // check it's not the first or second element (new world or tutorial)
1793 if(m_iSaveListIndex > (m_iDefaultButtonsC-1))
1794 {
1795 return true;
1796 }
1797 }
1798 return false;
1799}
1800
1801bool UIScene_LoadOrJoinMenu::DoesMashUpWorldHaveFocus()
1802{
1803 if(m_buttonListSaves.hasFocus())
1804 {
1805 // check it's not the first or second element (new world or tutorial)
1806 if(m_iSaveListIndex > (m_iDefaultButtonsC - 1))
1807 {
1808 return false;
1809 }
1810
1811 if(m_iSaveListIndex > (m_iDefaultButtonsC - 1 - m_iMashUpButtonsC))
1812 {
1813 return true;
1814 }
1815 else return false;
1816 }
1817 else return false;
1818}
1819
1820bool UIScene_LoadOrJoinMenu::DoesGamesListHaveFocus()
1821{
1822 return m_buttonListGames.hasFocus();
1823}
1824
1825void UIScene_LoadOrJoinMenu::handleTimerComplete(int id)
1826{
1827 switch(id)
1828 {
1829 case JOIN_LOAD_ONLINE_TIMER_ID:
1830 {
1831#ifdef _XBOX
1832 XPARTY_USER_LIST partyList;
1833
1834 if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) && (partyList.dwUserCount>1))
1835 {
1836 m_bInParty=true;
1837 }
1838 else
1839 {
1840 m_bInParty=false;
1841 }
1842#endif
1843
1844 bool bMultiplayerAllowed = ProfileManager.IsSignedInLive( m_iPad ) && ProfileManager.AllowedToPlayMultiplayer(m_iPad);
1845 if(bMultiplayerAllowed != m_bMultiplayerAllowed)
1846 {
1847 if( bMultiplayerAllowed )
1848 {
1849 // m_CheckboxOnline.SetEnable(TRUE);
1850 // m_CheckboxPrivate.SetEnable(TRUE);
1851 }
1852 else
1853 {
1854 m_bInParty = false;
1855 m_buttonListGames.clearList();
1856 m_controlJoinTimer.setVisible( true );
1857 m_labelNoGames.setVisible( false );
1858 }
1859
1860 m_bMultiplayerAllowed = bMultiplayerAllowed;
1861 }
1862 }
1863 break;
1864 // 4J-PB - Only Xbox will not have trial DLC patched into the game
1865#ifdef _XBOX
1866 case CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID:
1867 {
1868
1869#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__)
1870 for(int i=0;i<m_iTexturePacksNotInstalled;i++)
1871 {
1872 if(m_iConfigA[i]!=-1)
1873 {
1874 DLC_INFO *pDLCInfo=app.GetDLCInfoFromTPackID(m_iConfigA[i]);
1875
1876 if(pDLCInfo)
1877 {
1878 // retrieve the image - if we haven't already
1879 wstring textureName = filenametowstring(pDLCInfo->chImageURL);
1880
1881 if(hasRegisteredSubstitutionTexture(textureName)==false)
1882 {
1883 PBYTE pbImageData;
1884 int iImageDataBytes=0;
1885 SonyHttp::getDataFromURL(pDLCInfo->chImageURL,(void **)&pbImageData,&iImageDataBytes);
1886
1887 if(iImageDataBytes!=0)
1888 {
1889 // set the image
1890 registerSubstitutionTexture(textureName,pbImageData,iImageDataBytes,true);
1891 m_iConfigA[i]=-1;
1892 }
1893
1894 }
1895 }
1896 }
1897 }
1898
1899 bool bAllDone=true;
1900 for(int i=0;i<m_iTexturePacksNotInstalled;i++)
1901 {
1902 if(m_iConfigA[i]!=-1)
1903 {
1904 bAllDone = false;
1905 }
1906 }
1907
1908 if(bAllDone)
1909 {
1910 // kill this timer
1911 killTimer(CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
1912 }
1913#endif
1914
1915 }
1916 break;
1917#endif
1918 }
1919
1920}
1921
1922void UIScene_LoadOrJoinMenu::LoadSaveFromDisk(File *saveFile, ESavePlatform savePlatform /*= SAVE_FILE_PLATFORM_LOCAL*/)
1923{
1924 // we'll only be coming in here when the tutorial is loaded now
1925
1926 StorageManager.ResetSaveData();
1927
1928 // Make our next save default to the name of the level
1929 StorageManager.SetSaveTitle(saveFile->getName().c_str());
1930
1931 __int64 fileSize = saveFile->length();
1932 FileInputStream fis(*saveFile);
1933 byteArray ba(fileSize);
1934 fis.read(ba);
1935 fis.close();
1936
1937
1938
1939 bool isClientSide = false;
1940 bool isPrivate = false;
1941 int maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
1942
1943 if( app.GetTutorialMode() )
1944 {
1945 isClientSide = false;
1946 maxPlayers = 4;
1947 }
1948
1949 app.SetGameHostOption(eGameHostOption_GameType,GameType::CREATIVE->getId() );
1950
1951 g_NetworkManager.HostGame(0,isClientSide,isPrivate,maxPlayers,0);
1952
1953 LoadSaveDataThreadParam *saveData = new LoadSaveDataThreadParam(ba.data, ba.length, saveFile->getName());
1954
1955 NetworkGameInitData *param = new NetworkGameInitData();
1956 param->seed = 0;
1957 param->saveData = saveData;
1958 param->settings = app.GetGameHostOption( eGameHostOption_All );
1959 param->savePlatform = savePlatform;
1960
1961#ifndef _XBOX
1962 g_NetworkManager.FakeLocalPlayerJoined();
1963#endif
1964
1965 LoadingInputParams *loadingParams = new LoadingInputParams();
1966 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
1967 loadingParams->lpParam = (LPVOID)param;
1968
1969 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
1970 completionData->bShowBackground=TRUE;
1971 completionData->bShowLogo=TRUE;
1972 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
1973 completionData->iPad = DEFAULT_XUI_MENU_USER;
1974 loadingParams->completionData = completionData;
1975
1976 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams);
1977}
1978
1979#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
1980void UIScene_LoadOrJoinMenu::LoadSaveFromCloud()
1981{
1982
1983 wchar_t wFileName[128];
1984 mbstowcs(wFileName, app.getRemoteStorage()->getLocalFilename(), strlen(app.getRemoteStorage()->getLocalFilename())+1); // plus null
1985 File cloudFile(wFileName);
1986
1987
1988 StorageManager.ResetSaveData();
1989
1990 // Make our next save default to the name of the level
1991 wchar_t wSaveName[128];
1992 mbstowcs(wSaveName, app.getRemoteStorage()->getSaveNameUTF8(), strlen(app.getRemoteStorage()->getSaveNameUTF8())+1); // plus null
1993 StorageManager.SetSaveTitle(wSaveName);
1994
1995 __int64 fileSize = cloudFile.length();
1996 FileInputStream fis(cloudFile);
1997 byteArray ba(fileSize);
1998 fis.read(ba);
1999 fis.close();
2000
2001
2002
2003 bool isClientSide = false;
2004 bool isPrivate = false;
2005 int maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
2006
2007 if( app.GetTutorialMode() )
2008 {
2009 isClientSide = false;
2010 maxPlayers = 4;
2011 }
2012
2013 app.SetGameHostOption(eGameHostOption_All, app.getRemoteStorage()->getSaveHostOptions() );
2014
2015 g_NetworkManager.HostGame(0,isClientSide,isPrivate,maxPlayers,0);
2016
2017 LoadSaveDataThreadParam *saveData = new LoadSaveDataThreadParam(ba.data, ba.length, cloudFile.getName());
2018
2019 NetworkGameInitData *param = new NetworkGameInitData();
2020 param->seed = app.getRemoteStorage()->getSaveSeed();
2021 param->saveData = saveData;
2022 param->settings = app.GetGameHostOption( eGameHostOption_All );
2023 param->savePlatform = app.getRemoteStorage()->getSavePlatform();
2024 param->texturePackId = app.getRemoteStorage()->getSaveTexturePack();
2025
2026#ifndef _XBOX
2027 g_NetworkManager.FakeLocalPlayerJoined();
2028#endif
2029
2030 LoadingInputParams *loadingParams = new LoadingInputParams();
2031 loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
2032 loadingParams->lpParam = (LPVOID)param;
2033
2034 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
2035 completionData->bShowBackground=TRUE;
2036 completionData->bShowLogo=TRUE;
2037 completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
2038 completionData->iPad = DEFAULT_XUI_MENU_USER;
2039 loadingParams->completionData = completionData;
2040
2041 ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams);
2042}
2043
2044#endif //SONY_REMOTE_STORAGE_DOWNLOAD
2045
2046int UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
2047{
2048 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2049 // results switched for this dialog
2050
2051 // Check that we have a valid save selected (can get a bad index if the save list has been refreshed)
2052 bool validSelection= pClass->m_iDefaultButtonsC != 0 && pClass->m_iSaveListIndex >= pClass->m_iDefaultButtonsC;
2053
2054 if(result==C4JStorage::EMessage_ResultDecline && validSelection)
2055 {
2056 if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled())
2057 {
2058 pClass->m_bIgnoreInput=false;
2059 }
2060 else
2061 {
2062 StorageManager.DeleteSaveData(&pClass->m_pSaveDetails->SaveInfoA[pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC], UIScene_LoadOrJoinMenu::DeleteSaveDataReturned, (LPVOID)pClass->GetCallbackUniqueId());
2063 pClass->m_controlSavesTimer.setVisible( true );
2064 }
2065 }
2066 else
2067 {
2068 pClass->m_bIgnoreInput=false;
2069 }
2070
2071 return 0;
2072}
2073
2074int UIScene_LoadOrJoinMenu::DeleteSaveDataReturned(LPVOID lpParam,bool bRes)
2075{
2076 ui.EnterCallbackIdCriticalSection();
2077 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParam);
2078
2079 if(pClass)
2080 {
2081 if(bRes)
2082 {
2083 // wipe the list and repopulate it
2084 pClass->m_iState=e_SavesRepopulateAfterDelete;
2085 }
2086 else pClass->m_bIgnoreInput=false;
2087
2088 pClass->updateTooltips();
2089 }
2090 ui.LeaveCallbackIdCriticalSection();
2091 return 0;
2092}
2093
2094
2095int UIScene_LoadOrJoinMenu::RenameSaveDataReturned(LPVOID lpParam,bool bRes)
2096{
2097 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)lpParam;
2098
2099 if(bRes)
2100 {
2101 pClass->m_iState=e_SavesRepopulate;
2102 }
2103 else pClass->m_bIgnoreInput=false;
2104
2105 pClass->updateTooltips();
2106
2107 return 0;
2108}
2109
2110#ifdef __ORBIS__
2111
2112
2113void UIScene_LoadOrJoinMenu::LoadRemoteFileFromDisk(char* remoteFilename)
2114{
2115 wchar_t wSaveName[128];
2116 mbstowcs(wSaveName, remoteFilename, strlen(remoteFilename)+1); // plus null
2117
2118 // processConsoleSave(wSaveName, L"ProcessedSave.bin");
2119
2120 // File remoteFile(L"ProcessedSave.bin");
2121 File remoteFile(wSaveName);
2122 LoadSaveFromDisk(&remoteFile, SAVE_FILE_PLATFORM_PS3);
2123}
2124#endif
2125
2126
2127int UIScene_LoadOrJoinMenu::SaveOptionsDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
2128{
2129 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2130
2131 // results switched for this dialog
2132 // EMessage_ResultAccept means cancel
2133 switch(result)
2134 {
2135 case C4JStorage::EMessage_ResultDecline: // rename
2136 {
2137 pClass->m_bIgnoreInput=true;
2138#ifdef _DURANGO
2139 // bring up a keyboard
2140 InputManager.RequestKeyboard(app.GetString(IDS_RENAME_WORLD_TITLE), (pClass->m_saveDetails[pClass->m_iSaveListIndex-pClass->m_iDefaultButtonsC]).UTF16SaveName,(DWORD)0,25,&UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback,pClass,C_4JInput::EKeyboardMode_Default);
2141#else
2142 // bring up a keyboard
2143 wchar_t wSaveName[128];
2144 //CD - Fix - We must memset the SaveName
2145 ZeroMemory(wSaveName, 128 * sizeof(wchar_t) );
2146 mbstowcs(wSaveName, pClass->m_saveDetails[pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC].UTF8SaveName, strlen(pClass->m_saveDetails->UTF8SaveName)+1); // plus null
2147 LPWSTR ptr = wSaveName;
2148 InputManager.RequestKeyboard(app.GetString(IDS_RENAME_WORLD_TITLE),wSaveName,(DWORD)0,25,&UIScene_LoadOrJoinMenu::KeyboardCompleteWorldNameCallback,pClass,C_4JInput::EKeyboardMode_Default);
2149#endif
2150 }
2151 break;
2152
2153 case C4JStorage::EMessage_ResultThirdOption: // delete -
2154 {
2155 // delete the save game
2156 // Have to ask the player if they are sure they want to delete this game
2157 UINT uiIDA[2];
2158 uiIDA[0]=IDS_CONFIRM_CANCEL;
2159 uiIDA[1]=IDS_CONFIRM_OK;
2160 ui.RequestAlertMessage(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, iPad,&UIScene_LoadOrJoinMenu::DeleteSaveDialogReturned,pClass);
2161 }
2162 break;
2163
2164#ifdef SONY_REMOTE_STORAGE_UPLOAD
2165 case C4JStorage::EMessage_ResultFourthOption: // upload to cloud
2166 {
2167 UINT uiIDA[2];
2168 uiIDA[0]=IDS_CONFIRM_OK;
2169 uiIDA[1]=IDS_CONFIRM_CANCEL;
2170
2171 ui.RequestAlertMessage(IDS_TOOLTIPS_SAVETRANSFER_UPLOAD, IDS_SAVE_TRANSFER_TEXT, uiIDA, 2, iPad,&UIScene_LoadOrJoinMenu::SaveTransferDialogReturned,pClass);
2172 }
2173 break;
2174#endif // SONY_REMOTE_STORAGE_UPLOAD
2175#if defined _XBOX_ONE || defined __ORBIS__
2176 case C4JStorage::EMessage_ResultFourthOption: // copy save
2177 {
2178 UINT uiIDA[2];
2179 uiIDA[0]=IDS_CONFIRM_OK;
2180 uiIDA[1]=IDS_CONFIRM_CANCEL;
2181
2182 ui.RequestAlertMessage(IDS_COPYSAVE, IDS_TEXT_COPY_SAVE, uiIDA, 2, iPad,&UIScene_LoadOrJoinMenu::CopySaveDialogReturned,pClass);
2183 }
2184 break;
2185#endif
2186
2187 case C4JStorage::EMessage_Cancelled:
2188 default:
2189 {
2190 // reset the tooltips
2191 pClass->updateTooltips();
2192 pClass->m_bIgnoreInput=false;
2193 }
2194 break;
2195 }
2196 return 0;
2197}
2198
2199
2200#if defined (__PSVITA__)
2201
2202int UIScene_LoadOrJoinMenu::SignInAdhocReturned(void *pParam,bool bContinue, int iPad)
2203{
2204 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2205 pClass->m_bIgnoreInput = false;
2206 return 0;
2207
2208}
2209
2210
2211
2212int UIScene_LoadOrJoinMenu::MustSignInTexturePack(void *pParam,int iPad,C4JStorage::EMessageResult result)
2213{
2214 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2215
2216 if(result==C4JStorage::EMessage_ResultAccept)
2217 {
2218 SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_LoadOrJoinMenu::MustSignInReturnedTexturePack, pClass);
2219 }
2220 else
2221 {
2222 pClass->m_bIgnoreInput = false;
2223 }
2224
2225 return 0;
2226}
2227
2228
2229int UIScene_LoadOrJoinMenu::MustSignInReturnedTexturePack(void *pParam,bool bContinue, int iPad)
2230{
2231 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2232
2233 int commerceState = app.GetCommerceState();
2234 while( commerceState != CConsoleMinecraftApp::eCommerce_State_Offline &&
2235 commerceState != CConsoleMinecraftApp::eCommerce_State_Online &&
2236 commerceState != CConsoleMinecraftApp::eCommerce_State_Error)
2237 {
2238 Sleep(10);
2239 commerceState = app.GetCommerceState();
2240 }
2241
2242 if(bContinue==true)
2243 {
2244 SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo(pClass->m_initData->selectedSession->data.texturePackParentId);
2245 if(pSONYDLCInfo!=NULL)
2246 {
2247 char chName[42];
2248 char chKeyName[20];
2249 char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN];
2250
2251 memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN);
2252 // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it.
2253 // So we assume the first sku for the product is the one we want
2254 // MGH - keyname in the DLC file is 16 chars long, but there's no space for a NULL terminating char
2255 memset(chKeyName, 0, sizeof(chKeyName));
2256 strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16);
2257
2258#ifdef __ORBIS__
2259 strcpy(chName, chKeyName);
2260#else
2261 sprintf(chName,"%s-%s",app.GetCommerceCategory(),chKeyName);
2262#endif
2263 app.GetDLCSkuIDFromProductList(chName,chSkuID);
2264 // 4J-PB - need to check for an empty store
2265 if(app.CheckForEmptyStore(iPad)==false)
2266 {
2267 if(app.DLCAlreadyPurchased(chSkuID))
2268 {
2269 app.DownloadAlreadyPurchased(chSkuID);
2270 }
2271 else
2272 {
2273 app.Checkout(chSkuID);
2274 }
2275 }
2276 }
2277 }
2278 pClass->m_bIgnoreInput = false;
2279 return 0;
2280}
2281
2282#endif
2283
2284int UIScene_LoadOrJoinMenu::TexturePackDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
2285{
2286 UIScene_LoadOrJoinMenu *pClass = (UIScene_LoadOrJoinMenu *)pParam;
2287
2288 // Exit with or without saving
2289 if(result==C4JStorage::EMessage_ResultAccept)
2290 {
2291 // we need to enable background downloading for the DLC
2292 XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW);
2293#if defined __PSVITA__ || defined __PS3__ || defined __ORBIS__
2294
2295#ifdef __PSVITA__
2296 if(!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) && CGameNetworkManager::usingAdhocMode())
2297 {
2298 // get them to sign in to online
2299 UINT uiIDA[2];
2300 uiIDA[0]=IDS_PRO_NOTONLINE_ACCEPT;
2301 uiIDA[1]=IDS_PRO_NOTONLINE_DECLINE;
2302 ui.RequestAlertMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 2, ProfileManager.GetPrimaryPad(),&UIScene_LoadOrJoinMenu::MustSignInTexturePack,pClass);
2303 return;
2304 }
2305#endif
2306
2307 SONYDLC *pSONYDLCInfo=app.GetSONYDLCInfo(pClass->m_initData->selectedSession->data.texturePackParentId);
2308 if(pSONYDLCInfo!=NULL)
2309 {
2310 char chName[42];
2311 char chKeyName[20];
2312 char chSkuID[SCE_NP_COMMERCE2_SKU_ID_LEN];
2313
2314 memset(chSkuID,0,SCE_NP_COMMERCE2_SKU_ID_LEN);
2315 // we have to retrieve the skuid from the store info, it can't be hardcoded since Sony may change it.
2316 // So we assume the first sku for the product is the one we want
2317 // MGH - keyname in the DLC file is 16 chars long, but there's no space for a NULL terminating char
2318 memset(chKeyName, 0, sizeof(chKeyName));
2319 strncpy(chKeyName, pSONYDLCInfo->chDLCKeyname, 16);
2320
2321#ifdef __ORBIS__
2322 strcpy(chName, chKeyName);
2323#else
2324 sprintf(chName,"%s-%s",app.GetCommerceCategory(),chKeyName);
2325#endif
2326 app.GetDLCSkuIDFromProductList(chName,chSkuID);
2327 // 4J-PB - need to check for an empty store
2328 if(app.CheckForEmptyStore(iPad)==false)
2329 {
2330 if(app.DLCAlreadyPurchased(chSkuID))
2331 {
2332 app.DownloadAlreadyPurchased(chSkuID);
2333 }
2334 else
2335 {
2336 app.Checkout(chSkuID);
2337 }
2338 }
2339 }
2340#endif
2341
2342
2343#if defined _XBOX_ONE
2344 if(ProfileManager.IsSignedIn(iPad))
2345 {
2346 if (ProfileManager.IsSignedInLive(iPad))
2347 {
2348 wstring ProductId;
2349 app.GetDLCFullOfferIDForPackID(pClass->m_initData->selectedSession->data.texturePackParentId,ProductId);
2350
2351 StorageManager.InstallOffer(1,(WCHAR *)ProductId.c_str(),NULL,NULL);
2352 }
2353 else
2354 {
2355 // 4J-JEV: Fix for XB1: #165863 - XR-074: Compliance: With no active network connection user is unable to convert from Trial to Full texture pack and is not messaged why.
2356 UINT uiIDA[1] = { IDS_CONFIRM_OK };
2357 ui.RequestErrorMessage(IDS_PRO_NOTONLINE_TITLE, IDS_PRO_XBOXLIVE_NOTIFICATION, uiIDA, 1, iPad);
2358 }
2359 }
2360#endif
2361
2362 }
2363 pClass->m_bIgnoreInput=false;
2364 return 0;
2365}
2366
2367#if defined __PS3__ || defined __PSVITA__ || defined __ORBIS__
2368int UIScene_LoadOrJoinMenu::MustSignInReturnedPSN(void *pParam,int iPad,C4JStorage::EMessageResult result)
2369{
2370 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2371
2372 if(result==C4JStorage::EMessage_ResultAccept)
2373 {
2374#if defined(__PS3__)
2375 SQRNetworkManager_PS3::AttemptPSNSignIn(&UIScene_LoadOrJoinMenu::PSN_SignInReturned, pClass);
2376#elif defined __PSVITA__
2377 SQRNetworkManager_Vita::AttemptPSNSignIn(&UIScene_LoadOrJoinMenu::PSN_SignInReturned, pClass);
2378#else
2379 SQRNetworkManager_Orbis::AttemptPSNSignIn(&UIScene_LoadOrJoinMenu::PSN_SignInReturned, pClass, false, iPad);
2380#endif
2381 }
2382 else
2383 {
2384 pClass->m_bIgnoreInput = false;
2385 }
2386
2387 return 0;
2388}
2389
2390int UIScene_LoadOrJoinMenu::PSN_SignInReturned(void *pParam,bool bContinue, int iPad)
2391{
2392 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
2393 if(bContinue==true)
2394 {
2395 switch(pClass->m_eAction)
2396 {
2397 case eAction_ViewInvites:
2398 // Check if we're signed in to LIVE
2399 if(ProfileManager.IsSignedInLive(iPad))
2400 {
2401#if defined(__PS3__)
2402 int ret = sceNpBasicRecvMessageCustom(SCE_NP_BASIC_MESSAGE_MAIN_TYPE_INVITE, SCE_NP_BASIC_RECV_MESSAGE_OPTIONS_INCLUDE_BOOTABLE, SYS_MEMORY_CONTAINER_ID_INVALID);
2403 app.DebugPrintf("sceNpBasicRecvMessageCustom return %d ( %08x )\n", ret, ret);
2404#elif defined __PSVITA__
2405 SQRNetworkManager_Vita::RecvInviteGUI();
2406#else
2407 SQRNetworkManager_Orbis::RecvInviteGUI();
2408#endif
2409 }
2410 break;
2411 case eAction_JoinGame:
2412 pClass->CheckAndJoinGame(pClass->m_iGameListIndex);
2413 break;
2414 }
2415 }
2416 else
2417 {
2418 pClass->m_bIgnoreInput = false;
2419 }
2420 return 0;
2421}
2422#endif
2423
2424#ifdef SONY_REMOTE_STORAGE_DOWNLOAD
2425
2426void UIScene_LoadOrJoinMenu::LaunchSaveTransfer()
2427{
2428 LoadingInputParams *loadingParams = new LoadingInputParams();
2429 loadingParams->func = &UIScene_LoadOrJoinMenu::DownloadSonyCrossSaveThreadProc;
2430 loadingParams->lpParam = (LPVOID)this;
2431
2432 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
2433 completionData->bShowBackground=TRUE;
2434 completionData->bShowLogo=TRUE;
2435 completionData->type = e_ProgressCompletion_NavigateBackToScene;
2436 completionData->iPad = DEFAULT_XUI_MENU_USER;
2437 loadingParams->completionData = completionData;
2438
2439 loadingParams->cancelFunc=&UIScene_LoadOrJoinMenu::CancelSaveTransferCallback;
2440 loadingParams->m_cancelFuncParam=this;
2441 loadingParams->cancelText=IDS_TOOLTIPS_CANCEL;
2442
2443 ui.NavigateToScene(m_iPad,eUIScene_FullscreenProgress, loadingParams);
2444}
2445
2446
2447
2448
2449int UIScene_LoadOrJoinMenu::CreateDummySaveDataCallback(LPVOID lpParam,bool bRes)
2450{
2451 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
2452 if(bRes)
2453 {
2454 pClass->m_eSaveTransferState = eSaveTransfer_GetSavesInfo;
2455 }
2456 else
2457 {
2458 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2459 app.DebugPrintf("CreateDummySaveDataCallback failed\n");
2460
2461 }
2462 return 0;
2463}
2464
2465int UIScene_LoadOrJoinMenu::CrossSaveGetSavesInfoCallback(LPVOID lpParam, SAVE_DETAILS *pSaveDetails, bool bRes)
2466{
2467 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
2468 if(bRes)
2469 {
2470 pClass->m_eSaveTransferState = eSaveTransfer_GetFileData;
2471 }
2472 else
2473 {
2474 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2475 app.DebugPrintf("CrossSaveGetSavesInfoCallback failed\n");
2476 }
2477 return 0;
2478}
2479
2480int UIScene_LoadOrJoinMenu::LoadCrossSaveDataCallback( void *pParam,bool bIsCorrupt, bool bIsOwner )
2481{
2482 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) pParam;
2483 if(bIsCorrupt == false && bIsOwner)
2484 {
2485 pClass->m_eSaveTransferState = eSaveTransfer_CreatingNewSave;
2486 }
2487 else
2488 {
2489 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2490 app.DebugPrintf("LoadCrossSaveDataCallback failed \n");
2491
2492 }
2493 return 0;
2494}
2495
2496int UIScene_LoadOrJoinMenu::CrossSaveFinishedCallback(void *pParam,int iPad,C4JStorage::EMessageResult result)
2497{
2498 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) pParam;
2499 pClass->m_eSaveTransferState = eSaveTransfer_Idle;
2500 return 0;
2501}
2502
2503
2504int UIScene_LoadOrJoinMenu::CrossSaveDeleteOnErrorReturned(LPVOID lpParam,bool bRes)
2505{
2506 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
2507 pClass->m_eSaveTransferState = eSaveTransfer_ErrorMesssage;
2508 return 0;
2509}
2510
2511int UIScene_LoadOrJoinMenu::RemoteSaveNotFoundCallback(void *pParam,int iPad,C4JStorage::EMessageResult result)
2512{
2513 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) pParam;
2514 pClass->m_eSaveTransferState = eSaveTransfer_Idle;
2515 return 0;
2516}
2517
2518// MGH - added this global to force the delete of the previous data, for the remote storage saves
2519// need to speak to Chris why this is necessary
2520bool g_bForceVitaSaveWipe = false;
2521
2522
2523int UIScene_LoadOrJoinMenu::DownloadSonyCrossSaveThreadProc( LPVOID lpParameter )
2524{
2525 m_bSaveTransferRunning = true;
2526#ifdef __PS3__
2527 StorageManager.SetSaveTransferInProgress(true);
2528#endif
2529 Compression::UseDefaultThreadStorage();
2530 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParameter;
2531 pClass->m_saveTransferDownloadCancelled = false;
2532 m_bSaveTransferRunning = true;
2533 bool bAbortCalled = false;
2534 Minecraft *pMinecraft=Minecraft::GetInstance();
2535 bool bSaveFileCreated = false;
2536 wchar_t wSaveName[128];
2537
2538 // get the save file size
2539 pMinecraft->progressRenderer->progressStagePercentage(0);
2540 pMinecraft->progressRenderer->progressStart(IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD);
2541 pMinecraft->progressRenderer->progressStage( IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD );
2542
2543 ConsoleSaveFile* pSave = NULL;
2544
2545 pClass->m_eSaveTransferState = eSaveTransfer_GetRemoteSaveInfo;
2546
2547
2548 while(pClass->m_eSaveTransferState!=eSaveTransfer_Idle)
2549 {
2550 switch(pClass->m_eSaveTransferState)
2551 {
2552 case eSaveTransfer_Idle:
2553 break;
2554 case eSaveTransfer_GetRemoteSaveInfo:
2555 app.DebugPrintf("UIScene_LoadOrJoinMenu getSaveInfo\n");
2556 app.getRemoteStorage()->getSaveInfo();
2557 pClass->m_eSaveTransferState = eSaveTransfer_GettingRemoteSaveInfo;
2558 break;
2559 case eSaveTransfer_GettingRemoteSaveInfo:
2560 if(pClass->m_saveTransferDownloadCancelled)
2561 {
2562 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2563 break;
2564 }
2565 if(app.getRemoteStorage()->waitingForSaveInfo() == false)
2566 {
2567 if(app.getRemoteStorage()->saveIsAvailable())
2568 {
2569 if(app.getRemoteStorage()->saveVersionSupported())
2570 {
2571 pClass->m_eSaveTransferState = eSaveTransfer_CreateDummyFile;
2572 }
2573 else
2574 {
2575 // must be a newer version of the save in the cloud that we don't support yet
2576 UINT uiIDA[1];
2577 uiIDA[0]=IDS_CONFIRM_OK;
2578 ui.RequestAlertMessage(IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD, IDS_SAVE_TRANSFER_WRONG_VERSION, uiIDA, 1, ProfileManager.GetPrimaryPad(),RemoteSaveNotFoundCallback,pClass);
2579 }
2580 }
2581 else
2582 {
2583 // no save available, inform the user about the functionality
2584 UINT uiIDA[1];
2585 uiIDA[0]=IDS_CONFIRM_OK;
2586 ui.RequestAlertMessage(IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD, IDS_SAVE_TRANSFER_NOT_AVAILABLE_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(),RemoteSaveNotFoundCallback,pClass);
2587 }
2588 }
2589 break;
2590 case eSaveTransfer_CreateDummyFile:
2591 {
2592 StorageManager.ResetSaveData();
2593 byte *compData = (byte *)StorageManager.AllocateSaveData( app.getRemoteStorage()->getSaveFilesize() );
2594 // Make our next save default to the name of the level
2595 const char* pNameUTF8 = app.getRemoteStorage()->getSaveNameUTF8();
2596 mbstowcs(wSaveName, pNameUTF8, strlen(pNameUTF8)+1); // plus null
2597 StorageManager.SetSaveTitle(wSaveName);
2598 PBYTE pbThumbnailData=NULL;
2599 DWORD dwThumbnailDataSize=0;
2600
2601 PBYTE pbDataSaveImage=NULL;
2602 DWORD dwDataSizeSaveImage=0;
2603
2604 StorageManager.GetDefaultSaveImage(&pbDataSaveImage, &dwDataSizeSaveImage); // Get the default save thumbnail (as set by SetDefaultImages) for use on saving games t
2605 StorageManager.GetDefaultSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize); // Get the default save image (as set by SetDefaultImages) for use on saving games that
2606
2607 BYTE bTextMetadata[88];
2608 ZeroMemory(bTextMetadata,88);
2609 unsigned int hostOptions = app.getRemoteStorage()->getSaveHostOptions();
2610#ifdef __ORBIS__
2611 app.SetGameHostOption(hostOptions, eGameHostOption_WorldSize, e_worldSize_Classic); // force the classic world size on, otherwise it's unknown and we can't expand
2612#endif
2613 int iTextMetadataBytes = app.CreateImageTextData(bTextMetadata, app.getRemoteStorage()->getSaveSeed(), true, hostOptions, app.getRemoteStorage()->getSaveTexturePack() );
2614
2615 // set the icon and save image
2616 StorageManager.SetSaveImages(pbThumbnailData,dwThumbnailDataSize,pbDataSaveImage,dwDataSizeSaveImage,bTextMetadata,iTextMetadataBytes);
2617
2618 app.getRemoteStorage()->waitForStorageManagerIdle();
2619 C4JStorage::ESaveGameState saveState = StorageManager.SaveSaveData( &UIScene_LoadOrJoinMenu::CreateDummySaveDataCallback, lpParameter );
2620 if(saveState == C4JStorage::ESaveGame_Save)
2621 {
2622 pClass->m_eSaveTransferState = eSaveTransfer_CreatingDummyFile;
2623 }
2624 else
2625 {
2626 app.DebugPrintf("Failed to create dummy save file\n");
2627 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2628 }
2629 }
2630 break;
2631 case eSaveTransfer_CreatingDummyFile:
2632 break;
2633 case eSaveTransfer_GetSavesInfo:
2634 {
2635 // we can't cancel here, we need the saves info so we can delete the file
2636 if(pClass->m_saveTransferDownloadCancelled)
2637 {
2638 WCHAR wcTemp[256];
2639 swprintf(wcTemp,256, app.GetString(IDS_CANCEL)); // MGH - should change this string to "cancelling download"
2640 m_wstrStageText=wcTemp;
2641 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
2642 }
2643
2644 app.getRemoteStorage()->waitForStorageManagerIdle();
2645 app.DebugPrintf("CALL GetSavesInfo B\n");
2646 C4JStorage::ESaveGameState eSGIStatus= StorageManager.GetSavesInfo(pClass->m_iPad,&UIScene_LoadOrJoinMenu::CrossSaveGetSavesInfoCallback,pClass,"save");
2647 pClass->m_eSaveTransferState = eSaveTransfer_GettingSavesInfo;
2648 }
2649 break;
2650 case eSaveTransfer_GettingSavesInfo:
2651 if(pClass->m_saveTransferDownloadCancelled)
2652 {
2653 WCHAR wcTemp[256];
2654 swprintf(wcTemp,256, app.GetString(IDS_CANCEL)); // MGH - should change this string to "cancelling download"
2655 m_wstrStageText=wcTemp;
2656 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
2657 }
2658 break;
2659
2660 case eSaveTransfer_GetFileData:
2661 {
2662 bSaveFileCreated = true;
2663 StorageManager.GetSaveUniqueFileDir(pClass->m_downloadedUniqueFilename);
2664
2665 if(pClass->m_saveTransferDownloadCancelled)
2666 {
2667 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2668 break;
2669 }
2670 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
2671 int idx = pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC;
2672 app.getRemoteStorage()->waitForStorageManagerIdle();
2673 bool bGettingOK = app.getRemoteStorage()->getSaveData(pClass->m_downloadedUniqueFilename, SaveTransferReturned, pClass);
2674 if(bGettingOK)
2675 {
2676 pClass->m_eSaveTransferState = eSaveTransfer_GettingFileData;
2677 }
2678 else
2679 {
2680 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2681 app.DebugPrintf("app.getRemoteStorage()->getSaveData failed\n");
2682
2683 }
2684 }
2685
2686 case eSaveTransfer_GettingFileData:
2687 {
2688 WCHAR wcTemp[256];
2689
2690 int dataProgress = app.getRemoteStorage()->getDataProgress();
2691 pMinecraft->progressRenderer->progressStagePercentage(dataProgress);
2692
2693 //swprintf(wcTemp, 256, L"Downloading data : %d", dataProgress);//app.GetString(IDS_SAVETRANSFER_STAGE_GET_DATA),0,pClass->m_ulFileSize);
2694 swprintf(wcTemp,256, app.GetString(IDS_SAVETRANSFER_STAGE_GET_DATA),dataProgress);
2695 m_wstrStageText=wcTemp;
2696 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
2697 if(pClass->m_saveTransferDownloadCancelled && bAbortCalled == false)
2698 {
2699 app.getRemoteStorage()->abort();
2700 bAbortCalled = true;
2701 }
2702 }
2703 break;
2704 case eSaveTransfer_FileDataRetrieved:
2705 pClass->m_eSaveTransferState = eSaveTransfer_LoadSaveFromDisc;
2706 break;
2707 case eSaveTransfer_LoadSaveFromDisc:
2708 {
2709 if(pClass->m_saveTransferDownloadCancelled)
2710 {
2711 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2712 break;
2713 }
2714
2715 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
2716 int saveInfoIndex = -1;
2717 for(int i=0;i<pSaveDetails->iSaveC;i++)
2718 {
2719 if(strcmp(pSaveDetails->SaveInfoA[i].UTF8SaveFilename, pClass->m_downloadedUniqueFilename) == 0)
2720 {
2721 //found it
2722 saveInfoIndex = i;
2723 }
2724 }
2725 if(saveInfoIndex == -1)
2726 {
2727 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2728 app.DebugPrintf("CrossSaveGetSavesInfoCallback failed - couldn't find save\n");
2729 }
2730 else
2731 {
2732#ifdef __PS3__
2733 // ignore the CRC on PS3
2734 C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveData(&pSaveDetails->SaveInfoA[saveInfoIndex],&LoadCrossSaveDataCallback,pClass, true);
2735#else
2736 C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveData(&pSaveDetails->SaveInfoA[saveInfoIndex],&LoadCrossSaveDataCallback,pClass);
2737#endif
2738 if(eLoadStatus == C4JStorage::ESaveGame_Load)
2739 {
2740 pClass->m_eSaveTransferState = eSaveTransfer_LoadingSaveFromDisc;
2741 }
2742 else
2743 {
2744 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2745 }
2746 }
2747 }
2748 break;
2749 case eSaveTransfer_LoadingSaveFromDisc:
2750
2751 break;
2752 case eSaveTransfer_CreatingNewSave:
2753 {
2754 unsigned int fileSize = StorageManager.GetSaveSize();
2755 byteArray ba(fileSize);
2756 StorageManager.GetSaveData(ba.data, &fileSize);
2757 assert(ba.length == fileSize);
2758
2759
2760 StorageManager.ResetSaveData();
2761 {
2762 PBYTE pbThumbnailData=NULL;
2763 DWORD dwThumbnailDataSize=0;
2764
2765 PBYTE pbDataSaveImage=NULL;
2766 DWORD dwDataSizeSaveImage=0;
2767
2768 StorageManager.GetDefaultSaveImage(&pbDataSaveImage, &dwDataSizeSaveImage); // Get the default save thumbnail (as set by SetDefaultImages) for use on saving games t
2769 StorageManager.GetDefaultSaveThumbnail(&pbThumbnailData,&dwThumbnailDataSize); // Get the default save image (as set by SetDefaultImages) for use on saving games that
2770
2771 BYTE bTextMetadata[88];
2772 ZeroMemory(bTextMetadata,88);
2773 unsigned int remoteHostOptions = app.getRemoteStorage()->getSaveHostOptions();
2774 app.SetGameHostOption(eGameHostOption_All, remoteHostOptions );
2775 int iTextMetadataBytes = app.CreateImageTextData(bTextMetadata, app.getRemoteStorage()->getSaveSeed(), true, remoteHostOptions, app.getRemoteStorage()->getSaveTexturePack() );
2776
2777 // set the icon and save image
2778 StorageManager.SetSaveImages(pbThumbnailData,dwThumbnailDataSize,pbDataSaveImage,dwDataSizeSaveImage,bTextMetadata,iTextMetadataBytes);
2779 }
2780
2781
2782#ifdef SPLIT_SAVES
2783 ConsoleSaveFileOriginal oldFormatSave( wSaveName, ba.data, ba.length, false, app.getRemoteStorage()->getSavePlatform() );
2784 pSave = new ConsoleSaveFileSplit( &oldFormatSave, false, pMinecraft->progressRenderer );
2785
2786 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_STAGE_SAVING);
2787 pSave->Flush(false,false);
2788 pClass->m_eSaveTransferState = eSaveTransfer_Saving;
2789#else
2790 pSave = new ConsoleSaveFileOriginal( wSaveName, ba.data, ba.length, false, app.getRemoteStorage()->getSavePlatform() );
2791 pClass->m_eSaveTransferState = eSaveTransfer_Converting;
2792 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_STAGE_CONVERTING);
2793#endif
2794 delete ba.data;
2795 }
2796 break;
2797 case eSaveTransfer_Converting:
2798 {
2799 pSave->ConvertToLocalPlatform(); // check if we need to convert this file from PS3->PS4
2800 pClass->m_eSaveTransferState = eSaveTransfer_Saving;
2801 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_STAGE_SAVING);
2802 StorageManager.SetSaveTitle(wSaveName);
2803 StorageManager.SetSaveUniqueFilename(pClass->m_downloadedUniqueFilename);
2804
2805 app.getRemoteStorage()->waitForStorageManagerIdle(); // we need to wait for the save system to be idle here, as Flush doesn't check for it.
2806 pSave->Flush(false, false);
2807 }
2808 break;
2809 case eSaveTransfer_Saving:
2810 {
2811 // On Durango/Orbis, we need to wait for all the asynchronous saving processes to complete before destroying the levels, as that will ultimately delete
2812 // the directory level storage & therefore the ConsoleSaveSplit instance, which needs to be around until all the sub files have completed saving.
2813#if defined(_DURANGO) || defined(__ORBIS__)
2814 while(StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle )
2815 {
2816 Sleep(10);
2817 StorageManager.Tick();
2818 }
2819#endif
2820
2821 delete pSave;
2822
2823
2824 pMinecraft->progressRenderer->progressStage(IDS_PROGRESS_SAVING_TO_DISC);
2825 pClass->m_eSaveTransferState = eSaveTransfer_Succeeded;
2826 }
2827 break;
2828
2829 case eSaveTransfer_Succeeded:
2830 {
2831 // if we've arrived here, the save has been created successfully
2832 pClass->m_iState=e_SavesRepopulate;
2833 pClass->updateTooltips();
2834 UINT uiIDA[1];
2835 uiIDA[0]=IDS_CONFIRM_OK;
2836 app.getRemoteStorage()->waitForStorageManagerIdle(); // wait for everything to complete before we hand control back to the player
2837 ui.RequestErrorMessage( IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD, IDS_SAVE_TRANSFER_DOWNLOADCOMPLETE, uiIDA,1,ProfileManager.GetPrimaryPad(),CrossSaveFinishedCallback,pClass);
2838 pClass->m_eSaveTransferState = eSaveTransfer_Finished;
2839 }
2840 break;
2841
2842 case eSaveTransfer_Cancelled: // this is no longer used
2843 {
2844 assert(0); //pClass->m_eSaveTransferState = eSaveTransfer_Idle;
2845 }
2846 break;
2847 case eSaveTransfer_Error:
2848 {
2849 if(bSaveFileCreated)
2850 {
2851 if(pClass->m_saveTransferDownloadCancelled)
2852 {
2853 WCHAR wcTemp[256];
2854 swprintf(wcTemp,256, app.GetString(IDS_CANCEL)); // MGH - should change this string to "cancelling download"
2855 m_wstrStageText=wcTemp;
2856 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
2857 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
2858 }
2859 // if the save file has already been created we have to delete it again if there's been an error
2860 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
2861 int saveInfoIndex = -1;
2862 for(int i=0;i<pSaveDetails->iSaveC;i++)
2863 {
2864 if(strcmp(pSaveDetails->SaveInfoA[i].UTF8SaveFilename, pClass->m_downloadedUniqueFilename) == 0)
2865 {
2866 //found it
2867 saveInfoIndex = i;
2868 }
2869 }
2870 if(saveInfoIndex == -1)
2871 {
2872 app.DebugPrintf("eSaveTransfer_Error failed - couldn't find save\n");
2873 assert(0);
2874 pClass->m_eSaveTransferState = eSaveTransfer_ErrorMesssage;
2875 }
2876 else
2877 {
2878 // delete the save file
2879 app.getRemoteStorage()->waitForStorageManagerIdle();
2880 C4JStorage::ESaveGameState eDeleteStatus = StorageManager.DeleteSaveData(&pSaveDetails->SaveInfoA[saveInfoIndex],UIScene_LoadOrJoinMenu::CrossSaveDeleteOnErrorReturned,pClass);
2881 if(eDeleteStatus == C4JStorage::ESaveGame_Delete)
2882 {
2883 pClass->m_eSaveTransferState = eSaveTransfer_ErrorDeletingSave;
2884 }
2885 else
2886 {
2887 app.DebugPrintf("StorageManager.DeleteSaveData failed!!\n");
2888 pClass->m_eSaveTransferState = eSaveTransfer_ErrorMesssage;
2889 }
2890 }
2891 }
2892 else
2893 {
2894 pClass->m_eSaveTransferState = eSaveTransfer_ErrorMesssage;
2895 }
2896 }
2897 break;
2898
2899 case eSaveTransfer_ErrorDeletingSave:
2900 break;
2901 case eSaveTransfer_ErrorMesssage:
2902 {
2903 app.getRemoteStorage()->waitForStorageManagerIdle(); // wait for everything to complete before we hand control back to the player
2904 if(pClass->m_saveTransferDownloadCancelled)
2905 {
2906 pClass->m_eSaveTransferState = eSaveTransfer_Idle;
2907 }
2908 else
2909 {
2910 UINT uiIDA[1];
2911 uiIDA[0]=IDS_CONFIRM_OK;
2912 UINT errorMessage = IDS_SAVE_TRANSFER_DOWNLOADFAILED;
2913 if(!ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()))
2914 {
2915 errorMessage = IDS_ERROR_NETWORK; // show "A network error has occurred."
2916#ifdef __ORBIS__
2917 if(!ProfileManager.isSignedInPSN(ProfileManager.GetPrimaryPad()))
2918 {
2919 errorMessage = IDS_PRO_NOTONLINE_TEXT; // show "not signed into PSN"
2920 }
2921#endif
2922#ifdef __VITA__
2923 if(!ProfileManager.IsSignedInPSN(ProfileManager.GetPrimaryPad()))
2924 {
2925 errorMessage = IDS_PRO_NOTONLINE_TEXT; // show "not signed into PSN"
2926 }
2927#endif
2928
2929 }
2930 ui.RequestErrorMessage( IDS_TOOLTIPS_SAVETRANSFER_DOWNLOAD, errorMessage, uiIDA,1,ProfileManager.GetPrimaryPad(),CrossSaveFinishedCallback,pClass);
2931 pClass->m_eSaveTransferState = eSaveTransfer_Finished;
2932 }
2933 if(bSaveFileCreated) // save file has been created, then deleted.
2934 pClass->m_iState=e_SavesRepopulateAfterDelete;
2935 else
2936 pClass->m_iState=e_SavesRepopulate;
2937 pClass->updateTooltips();
2938 }
2939 break;
2940 case eSaveTransfer_Finished:
2941 {
2942 }
2943 // waiting to dismiss the dialog
2944 break;
2945 }
2946 Sleep(50);
2947 }
2948 m_bSaveTransferRunning = false;
2949#ifdef __PS3__
2950 StorageManager.SetSaveTransferInProgress(false);
2951#endif
2952 return 0;
2953
2954}
2955
2956void UIScene_LoadOrJoinMenu::SaveTransferReturned(LPVOID lpParam, SonyRemoteStorage::Status s, int error_code)
2957{
2958 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
2959
2960 if(s == SonyRemoteStorage::e_getDataSucceeded)
2961 {
2962 pClass->m_eSaveTransferState = eSaveTransfer_FileDataRetrieved;
2963 }
2964 else
2965 {
2966 pClass->m_eSaveTransferState = eSaveTransfer_Error;
2967 app.DebugPrintf("SaveTransferReturned failed with error code : 0x%08x\n", error_code);
2968 }
2969
2970}
2971ConsoleSaveFile* UIScene_LoadOrJoinMenu::SonyCrossSaveConvert()
2972{
2973 return NULL;
2974}
2975
2976void UIScene_LoadOrJoinMenu::CancelSaveTransferCallback(LPVOID lpParam)
2977{
2978 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
2979 pClass->m_saveTransferDownloadCancelled = true;
2980 ui.SetTooltips( DEFAULT_XUI_MENU_USER, -1, -1, -1, -1,-1,-1,-1,-1); // MGH - added - remove the "cancel" tooltip, so the player knows it's underway (really needs a "cancelling" message)
2981}
2982
2983#endif
2984
2985
2986
2987#ifdef SONY_REMOTE_STORAGE_UPLOAD
2988
2989void UIScene_LoadOrJoinMenu::LaunchSaveUpload()
2990{
2991 LoadingInputParams *loadingParams = new LoadingInputParams();
2992 loadingParams->func = &UIScene_LoadOrJoinMenu::UploadSonyCrossSaveThreadProc;
2993 loadingParams->lpParam = (LPVOID)this;
2994
2995 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
2996 completionData->bShowBackground=TRUE;
2997 completionData->bShowLogo=TRUE;
2998 completionData->type = e_ProgressCompletion_NavigateBackToScene;
2999 completionData->iPad = DEFAULT_XUI_MENU_USER;
3000 loadingParams->completionData = completionData;
3001
3002// 4J-PB - Waiting for Sony to fix canceling a save upload
3003 loadingParams->cancelFunc=&UIScene_LoadOrJoinMenu::CancelSaveUploadCallback;
3004 loadingParams->m_cancelFuncParam = this;
3005 loadingParams->cancelText=IDS_TOOLTIPS_CANCEL;
3006
3007 ui.NavigateToScene(m_iPad,eUIScene_FullscreenProgress, loadingParams);
3008
3009}
3010
3011int UIScene_LoadOrJoinMenu::CrossSaveUploadFinishedCallback(void *pParam,int iPad,C4JStorage::EMessageResult result)
3012{
3013 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) pParam;
3014 pClass->m_eSaveUploadState = eSaveUpload_Idle;
3015
3016 return 0;
3017}
3018
3019
3020int UIScene_LoadOrJoinMenu::UploadSonyCrossSaveThreadProc( LPVOID lpParameter )
3021{
3022 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParameter;
3023 pClass->m_saveTransferUploadCancelled = false;
3024 bool bAbortCalled = false;
3025 Minecraft *pMinecraft=Minecraft::GetInstance();
3026
3027 // get the save file size
3028 pMinecraft->progressRenderer->progressStagePercentage(0);
3029 pMinecraft->progressRenderer->progressStart(IDS_TOOLTIPS_SAVETRANSFER_UPLOAD);
3030 pMinecraft->progressRenderer->progressStage( IDS_TOOLTIPS_SAVETRANSFER_UPLOAD );
3031
3032 PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo();
3033 int idx = pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC;
3034 bool bSettingOK = app.getRemoteStorage()->setSaveData(&pSaveDetails->SaveInfoA[idx], SaveUploadReturned, pClass);
3035
3036 if(bSettingOK)
3037 {
3038 pClass->m_eSaveUploadState = eSaveUpload_UploadingFileData;
3039 pMinecraft->progressRenderer->progressStagePercentage(0);
3040 }
3041 else
3042 {
3043 pClass->m_eSaveUploadState = eSaveUpload_Error;
3044 }
3045
3046 while(pClass->m_eSaveUploadState!=eSaveUpload_Idle)
3047 {
3048 switch(pClass->m_eSaveUploadState)
3049 {
3050 case eSaveUpload_Idle:
3051 break;
3052 case eSaveUpload_UploadingFileData:
3053 {
3054 WCHAR wcTemp[256];
3055 int dataProgress = app.getRemoteStorage()->getDataProgress();
3056 pMinecraft->progressRenderer->progressStagePercentage(dataProgress);
3057
3058 //swprintf(wcTemp, 256, L"Uploading data : %d", dataProgress);//app.GetString(IDS_SAVETRANSFER_STAGE_GET_DATA),0,pClass->m_ulFileSize);
3059 swprintf(wcTemp,256, app.GetString(IDS_SAVETRANSFER_STAGE_PUT_DATA),dataProgress);
3060
3061 m_wstrStageText=wcTemp;
3062 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
3063// 4J-PB - Waiting for Sony to fix canceling a save upload
3064 if(pClass->m_saveTransferUploadCancelled && bAbortCalled == false)
3065 {
3066 // we only really want to be able to cancel during the download of data, if it's taking a long time
3067 app.getRemoteStorage()->abort();
3068 bAbortCalled = true;
3069 }
3070 }
3071 break;
3072 case eSaveUpload_FileDataUploaded:
3073 {
3074 UINT uiIDA[1];
3075 uiIDA[0]=IDS_CONFIRM_OK;
3076 ui.RequestErrorMessage( IDS_TOOLTIPS_SAVETRANSFER_UPLOAD, IDS_SAVE_TRANSFER_UPLOADCOMPLETE, uiIDA,1,ProfileManager.GetPrimaryPad(),CrossSaveUploadFinishedCallback,pClass);
3077 pClass->m_eSaveUploadState = esaveUpload_Finished;
3078 }
3079 break;
3080 case eSaveUpload_Cancelled: // this is no longer used
3081 assert(0);// pClass->m_eSaveUploadState = eSaveUpload_Idle;
3082 break;
3083 case eSaveUpload_Error:
3084 {
3085 if(pClass->m_saveTransferUploadCancelled)
3086 {
3087 pClass->m_eSaveUploadState = eSaveUpload_Idle;
3088 }
3089 else
3090 {
3091 UINT uiIDA[1];
3092 uiIDA[0]=IDS_CONFIRM_OK;
3093 ui.RequestErrorMessage( IDS_TOOLTIPS_SAVETRANSFER_UPLOAD, IDS_SAVE_TRANSFER_UPLOADFAILED, uiIDA,1,ProfileManager.GetPrimaryPad(),CrossSaveUploadFinishedCallback,pClass);
3094 pClass->m_eSaveUploadState = esaveUpload_Finished;
3095 }
3096 }
3097 break;
3098 case esaveUpload_Finished:
3099 // waiting for dialog to be dismissed
3100 break;
3101 }
3102 Sleep(50);
3103 }
3104
3105 return 0;
3106
3107}
3108
3109void UIScene_LoadOrJoinMenu::SaveUploadReturned(LPVOID lpParam, SonyRemoteStorage::Status s, int error_code)
3110{
3111 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
3112
3113 if(pClass->m_saveTransferUploadCancelled)
3114 {
3115 UINT uiIDA[1] = { IDS_CONFIRM_OK };
3116 ui.RequestErrorMessage( IDS_CANCEL_UPLOAD_TITLE, IDS_CANCEL_UPLOAD_TEXT, uiIDA, 1, ProfileManager.GetPrimaryPad(), CrossSaveUploadFinishedCallback, pClass );
3117 pClass->m_eSaveUploadState=esaveUpload_Finished;
3118 }
3119 else
3120 {
3121 if(s == SonyRemoteStorage::e_setDataSucceeded)
3122 pClass->m_eSaveUploadState = eSaveUpload_FileDataUploaded;
3123 else if ( !pClass->m_saveTransferUploadCancelled )
3124 pClass->m_eSaveUploadState = eSaveUpload_Error;
3125 }
3126}
3127
3128void UIScene_LoadOrJoinMenu::CancelSaveUploadCallback(LPVOID lpParam)
3129{
3130 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu *) lpParam;
3131 pClass->m_saveTransferUploadCancelled = true;
3132 app.DebugPrintf("m_saveTransferUploadCancelled = true\n");
3133 ui.SetTooltips( DEFAULT_XUI_MENU_USER, -1, -1, -1, -1,-1,-1,-1,-1); // MGH - added - remove the "cancel" tooltip, so the player knows it's underway (really needs a "cancelling" message)
3134
3135 pClass->m_bIgnoreInput = true;
3136}
3137
3138int UIScene_LoadOrJoinMenu::SaveTransferDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
3139{
3140 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
3141 // results switched for this dialog
3142 if(result==C4JStorage::EMessage_ResultAccept)
3143 {
3144 // upload the save
3145 pClass->LaunchSaveUpload();
3146
3147 pClass->m_bIgnoreInput=false;
3148 }
3149 else
3150 {
3151 pClass->m_bIgnoreInput=false;
3152 }
3153 return 0;
3154}
3155#endif // SONY_REMOTE_STORAGE_UPLOAD
3156
3157
3158#if defined _XBOX_ONE
3159void UIScene_LoadOrJoinMenu::LaunchSaveTransfer()
3160{
3161 SaveTransferStateContainer *stateContainer = new SaveTransferStateContainer();
3162 stateContainer->m_iProgress = 0;
3163 stateContainer->m_bSaveTransferInProgress = false;
3164 stateContainer->m_bSaveTransferCancelled = false;
3165 stateContainer->m_iPad = m_iPad;
3166 stateContainer->m_eSaveTransferState = C4JStorage::eSaveTransfer_Idle;
3167 stateContainer->m_pClass = this;
3168
3169 LoadingInputParams *loadingParams = new LoadingInputParams();
3170 loadingParams->func = &UIScene_LoadOrJoinMenu::DownloadXbox360SaveThreadProc;
3171 loadingParams->lpParam = (LPVOID)stateContainer;
3172
3173 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
3174 completionData->bShowBackground=TRUE;
3175 completionData->bShowLogo=TRUE;
3176 completionData->type = e_ProgressCompletion_NavigateBackToScene;
3177 completionData->iPad = DEFAULT_XUI_MENU_USER;
3178 completionData->bRequiresUserAction=TRUE;
3179 loadingParams->completionData = completionData;
3180
3181 loadingParams->cancelFunc=&UIScene_LoadOrJoinMenu::CancelSaveTransferCallback;
3182 loadingParams->m_cancelFuncParam=stateContainer;
3183 loadingParams->cancelText=IDS_TOOLTIPS_CANCEL;
3184
3185 ui.NavigateToScene(m_iPad,eUIScene_FullscreenProgress, loadingParams);
3186}
3187
3188
3189
3190int UIScene_LoadOrJoinMenu::DownloadXbox360SaveThreadProc( LPVOID lpParameter )
3191{
3192 Compression::UseDefaultThreadStorage();
3193
3194 SaveTransferStateContainer *pStateContainer = (SaveTransferStateContainer *) lpParameter;
3195 Minecraft *pMinecraft=Minecraft::GetInstance();
3196 ConsoleSaveFile* pSave = NULL;
3197
3198 while(StorageManager.SaveTransferClearState()!=C4JStorage::eSaveTransfer_Idle)
3199 {
3200 Sleep(5);
3201 }
3202
3203 pStateContainer->m_bSaveTransferInProgress=true;
3204
3205 UIScene_LoadOrJoinMenu::s_eSaveTransferFile = eSaveTransferFile_Marker;
3206 RequestFileSize( pStateContainer, L"completemarker" );
3207
3208 while((pStateContainer->m_eSaveTransferState!=C4JStorage::eSaveTransfer_Idle) && pStateContainer->m_bSaveTransferInProgress && !pStateContainer->m_bSaveTransferCancelled)
3209 {
3210 switch(pStateContainer->m_eSaveTransferState)
3211 {
3212 case C4JStorage::eSaveTransfer_Idle:
3213 break;
3214 case C4JStorage::eSaveTransfer_FileSizeRetrieved:
3215 switch(UIScene_LoadOrJoinMenu::s_eSaveTransferFile)
3216 {
3217 case eSaveTransferFile_Marker:
3218 if(UIScene_LoadOrJoinMenu::s_ulFileSize == 0)
3219 {
3220 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_NONE_FOUND);
3221 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3222 }
3223 else
3224 {
3225 RequestFileData( pStateContainer, L"completemarker" );
3226 }
3227 break;
3228 case eSaveTransferFile_Metadata:
3229 RequestFileData( pStateContainer, L"metadata" );
3230 break;
3231 case eSaveTransferFile_SaveData:
3232 RequestFileData( pStateContainer, L"savedata" );
3233 break;
3234 };
3235 break;
3236 case C4JStorage::eSaveTransfer_GettingFileData:
3237
3238 break;
3239 case C4JStorage::eSaveTransfer_FileDataRetrieved:
3240 switch(UIScene_LoadOrJoinMenu::s_eSaveTransferFile)
3241 {
3242 case eSaveTransferFile_Marker:
3243 // MGH - the marker file now contains the save file version number
3244 // if the version is higher than we handle, cancel the download.
3245 if(UIScene_LoadOrJoinMenu::s_transferData[0] > SAVE_FILE_VERSION_NUMBER)
3246 {
3247 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_NONE_FOUND);
3248 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3249 }
3250 else
3251 {
3252 UIScene_LoadOrJoinMenu::s_eSaveTransferFile = eSaveTransferFile_Metadata;
3253 RequestFileSize( pStateContainer, L"metadata" );
3254 }
3255 break;
3256 case eSaveTransferFile_Metadata:
3257 {
3258 ByteArrayInputStream bais(UIScene_LoadOrJoinMenu::s_transferData);
3259 DataInputStream dis(&bais);
3260
3261 wstring saveTitle = dis.readUTF();
3262 StorageManager.SetSaveTitle(saveTitle.c_str());
3263
3264 wstring saveUniqueName = dis.readUTF();
3265
3266 // 4J Stu - Don't set this any more. We added it so that we could share the ban list data for this save
3267 // However if the player downloads the same save multiple times, it will overwrite the previous version
3268 // with that filname, and they could have made changes to it.
3269 //StorageManager.SetSaveUniqueFilename((wchar_t *)saveUniqueName.c_str());
3270
3271 int thumbnailSize = dis.readInt();
3272 if(thumbnailSize > 0)
3273 {
3274 byteArray ba(thumbnailSize);
3275 dis.readFully(ba);
3276
3277
3278
3279 // retrieve the seed value from the image metadata, we need to change to host options, then set it back again
3280 bool bHostOptionsRead = false;
3281 unsigned int uiHostOptions = 0;
3282 DWORD dwTexturePack;
3283 __int64 seedVal;
3284
3285 char szSeed[50];
3286 ZeroMemory(szSeed,50);
3287 app.GetImageTextData(ba.data,ba.length,(unsigned char *)&szSeed,uiHostOptions,bHostOptionsRead,dwTexturePack);
3288 sscanf_s(szSeed, "%I64d", &seedVal);
3289
3290 app.SetGameHostOption(uiHostOptions, eGameHostOption_WorldSize, e_worldSize_Classic); // force the classic world size on, otherwise it's unknown and we can't expand
3291
3292
3293 BYTE bTextMetadata[88];
3294 ZeroMemory(bTextMetadata,88);
3295
3296 int iTextMetadataBytes = app.CreateImageTextData(bTextMetadata, seedVal, true, uiHostOptions, dwTexturePack);
3297 // set the icon and save image
3298 StorageManager.SetSaveImages(ba.data, ba.length, NULL, 0, bTextMetadata, iTextMetadataBytes);
3299
3300 delete ba.data;
3301 }
3302
3303 UIScene_LoadOrJoinMenu::s_transferData = byteArray();
3304 UIScene_LoadOrJoinMenu::s_eSaveTransferFile = eSaveTransferFile_SaveData;
3305 RequestFileSize( pStateContainer, L"savedata" );
3306 }
3307 break;
3308 case eSaveTransferFile_SaveData:
3309 {
3310#ifdef SPLIT_SAVES
3311 if(!pStateContainer->m_bSaveTransferCancelled)
3312 {
3313 ConsoleSaveFileOriginal oldFormatSave( L"Temp name", UIScene_LoadOrJoinMenu::s_transferData.data, UIScene_LoadOrJoinMenu::s_transferData.length, false, SAVE_FILE_PLATFORM_X360 );
3314 pSave = new ConsoleSaveFileSplit( &oldFormatSave, false, pMinecraft->progressRenderer );
3315
3316 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_STAGE_SAVING);
3317 if(!pStateContainer->m_bSaveTransferCancelled) pSave->Flush(false,false);
3318 }
3319 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Saving;
3320
3321#else
3322 pSave = new ConsoleSaveFileOriginal( wSaveName, m_transferData.data, m_transferData.length, false, SAVE_FILE_PLATFORM_X360 );
3323 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Converting;
3324#endif
3325 delete UIScene_LoadOrJoinMenu::s_transferData.data;
3326 UIScene_LoadOrJoinMenu::s_transferData = byteArray();
3327 }
3328 break;
3329 };
3330
3331 pStateContainer->m_iProgress=0;
3332 break;
3333 case C4JStorage::eSaveTransfer_Converting:
3334#if 0
3335 pSave->ConvertToLocalPlatform();
3336
3337 pMinecraft->progressRenderer->progressStage(IDS_SAVETRANSFER_STAGE_SAVING);
3338 if(!pStateContainer->m_bSaveTransferCancelled) pSave->Flush(false,false);
3339
3340 pStateContainer->m_iProgress+=1;
3341 if(pStateContainer->m_iProgress==101)
3342 {
3343 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Saving;
3344 pStateContainer->m_iProgress=0;
3345 break;
3346 }
3347 pMinecraft->progressRenderer->progressStagePercentage(pStateContainer->m_iProgress);
3348#endif
3349 break;
3350 case C4JStorage::eSaveTransfer_Saving:
3351 // On Durango/Orbis, we need to wait for all the asynchronous saving processes to complete before destroying the levels, as that will ultimately delete
3352 // the directory level storage & therefore the ConsoleSaveSplit instance, which needs to be around until all the sub files have completed saving.
3353#if defined(_DURANGO) || defined(__ORBIS__)
3354 pMinecraft->progressRenderer->progressStage(IDS_PROGRESS_SAVING_TO_DISC);
3355
3356 while(StorageManager.GetSaveState() != C4JStorage::ESaveGame_Idle )
3357 {
3358 Sleep(10);
3359
3360 // 4J Stu - DO NOT tick this here. The main thread should be the only place ticking the StorageManager. You WILL get crashes.
3361 //StorageManager.Tick();
3362 }
3363#endif
3364
3365 delete pSave;
3366
3367#ifdef _XBOX_ONE
3368 pMinecraft->progressRenderer->progressStage(IDS_SAVE_TRANSFER_DOWNLOAD_AND_CONVERT_COMPLETE);
3369#endif
3370
3371 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3372
3373 // wipe the list and repopulate it
3374 if(!pStateContainer->m_bSaveTransferCancelled) pStateContainer->m_pClass->m_iState=e_SavesRepopulateAfterTransferDownload;
3375
3376 //pClass->m_iProgress+=1;
3377 //if(pClass->m_iProgress==101)
3378 //{
3379 // pClass->m_iProgress=0;
3380 // pClass->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3381 // pMinecraft->progressRenderer->progressStage( IDS_SAVE_TRANSFER_DOWNLOAD_AND_CONVERT_COMPLETE );
3382
3383 // break;
3384 //}
3385 //pMinecraft->progressRenderer->progressStagePercentage(pClass->m_iProgress);
3386
3387 break;
3388 }
3389 Sleep(50);
3390 }
3391
3392 if(pStateContainer->m_bSaveTransferCancelled)
3393 {
3394 WCHAR wcTemp[256];
3395
3396 pStateContainer->m_bSaveTransferCancelled=false;
3397 swprintf(wcTemp,app.GetString(IDS_SAVE_TRANSFER_DOWNLOAD_CANCELLED));
3398 m_wstrStageText=wcTemp;
3399 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
3400
3401 }
3402
3403 pStateContainer->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3404 pStateContainer->m_bSaveTransferInProgress=false;
3405
3406 delete pStateContainer;
3407
3408 return 0;
3409}
3410
3411void UIScene_LoadOrJoinMenu::RequestFileSize( SaveTransferStateContainer *pClass, wchar_t *filename )
3412{
3413 Minecraft *pMinecraft=Minecraft::GetInstance();
3414
3415 // get the save file size
3416 pMinecraft->progressRenderer->progressStart(IDS_SAVETRANSFER_TITLE_GET);
3417 pMinecraft->progressRenderer->progressStage( IDS_SAVETRANSFER_STAGE_GET_DETAILS );
3418
3419#ifdef _DEBUG_MENUS_ENABLED
3420 if(app.GetLoadSavesFromFolderEnabled())
3421 {
3422 ZeroMemory(&m_debugTransferDetails, sizeof(C4JStorage::SAVETRANSFER_FILE_DETAILS) );
3423
3424 File targetFile( wstring(L"FakeTMSPP\\").append(filename) );
3425 if(targetFile.exists()) m_debugTransferDetails.ulFileLen = targetFile.length();
3426
3427 SaveTransferReturned(pClass,&m_debugTransferDetails);
3428 }
3429 else
3430#endif
3431 {
3432 do
3433 {
3434 pMinecraft->progressRenderer->progressStart(IDS_SAVETRANSFER_TITLE_GET);
3435 pMinecraft->progressRenderer->progressStage( IDS_SAVETRANSFER_STAGE_GET_DETAILS );
3436 Sleep(1);
3437 pClass->m_eSaveTransferState=StorageManager.SaveTransferGetDetails(pClass->m_iPad,C4JStorage::eGlobalStorage_TitleUser,filename,&UIScene_LoadOrJoinMenu::SaveTransferReturned,pClass);
3438 }
3439 while(pClass->m_eSaveTransferState == C4JStorage::eSaveTransfer_Busy && !pClass->m_bSaveTransferCancelled );
3440 }
3441}
3442
3443void UIScene_LoadOrJoinMenu::RequestFileData( SaveTransferStateContainer *pClass, wchar_t *filename )
3444{
3445 Minecraft *pMinecraft=Minecraft::GetInstance();
3446 WCHAR wcTemp[256];
3447
3448 pMinecraft->progressRenderer->progressStagePercentage(0);
3449
3450 swprintf(wcTemp,app.GetString(IDS_SAVETRANSFER_STAGE_GET_DATA),0,UIScene_LoadOrJoinMenu::s_ulFileSize);
3451 m_wstrStageText=wcTemp;
3452
3453 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
3454
3455#ifdef _DEBUG_MENUS_ENABLED
3456 if(app.GetLoadSavesFromFolderEnabled())
3457 {
3458 File targetFile( wstring(L"FakeTMSPP\\").append(filename) );
3459 if(targetFile.exists())
3460 {
3461 HANDLE hSaveFile = CreateFile( targetFile.getPath().c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);
3462
3463 m_debugTransferDetails.pbData = new BYTE[m_debugTransferDetails.ulFileLen];
3464
3465 DWORD numberOfBytesRead = 0;
3466 ReadFile( hSaveFile,m_debugTransferDetails.pbData,m_debugTransferDetails.ulFileLen,&numberOfBytesRead,NULL);
3467 assert(numberOfBytesRead == m_debugTransferDetails.ulFileLen);
3468
3469 CloseHandle(hSaveFile);
3470
3471 SaveTransferReturned(pClass,&m_debugTransferDetails);
3472 }
3473 }
3474 else
3475#endif
3476 {
3477 do
3478 {
3479 pMinecraft->progressRenderer->progressStart(IDS_SAVETRANSFER_TITLE_GET);
3480 pMinecraft->progressRenderer->progressStage( -1 );
3481 Sleep(1);
3482 pClass->m_eSaveTransferState=StorageManager.SaveTransferGetData(pClass->m_iPad,C4JStorage::eGlobalStorage_TitleUser,filename,&UIScene_LoadOrJoinMenu::SaveTransferReturned,&UIScene_LoadOrJoinMenu::SaveTransferUpdateProgress,pClass,pClass);
3483 }
3484 while(pClass->m_eSaveTransferState == C4JStorage::eSaveTransfer_Busy && !pClass->m_bSaveTransferCancelled );
3485 }
3486}
3487
3488int UIScene_LoadOrJoinMenu::SaveTransferReturned(LPVOID lpParam,C4JStorage::SAVETRANSFER_FILE_DETAILS *pSaveTransferDetails)
3489{
3490 SaveTransferStateContainer* pClass = (SaveTransferStateContainer *) lpParam;
3491 app.DebugPrintf("Save Transfer - size is %d\n",pSaveTransferDetails->ulFileLen);
3492
3493 // if the file data is null, then assume this is the file size retrieval
3494 if(pSaveTransferDetails->pbData==NULL)
3495 {
3496 pClass->m_eSaveTransferState=C4JStorage::eSaveTransfer_FileSizeRetrieved;
3497 UIScene_LoadOrJoinMenu::s_ulFileSize=pSaveTransferDetails->ulFileLen;
3498 }
3499 else
3500 {
3501 delete UIScene_LoadOrJoinMenu::s_transferData.data;
3502 UIScene_LoadOrJoinMenu::s_transferData = byteArray(pSaveTransferDetails->pbData, UIScene_LoadOrJoinMenu::s_ulFileSize);
3503 pClass->m_eSaveTransferState=C4JStorage::eSaveTransfer_FileDataRetrieved;
3504 }
3505
3506 return 0;
3507}
3508
3509int UIScene_LoadOrJoinMenu::SaveTransferUpdateProgress(LPVOID lpParam,unsigned long ulBytesReceived)
3510{
3511 WCHAR wcTemp[256];
3512
3513 SaveTransferStateContainer* pClass = (SaveTransferStateContainer *) lpParam;
3514 Minecraft *pMinecraft=Minecraft::GetInstance();
3515
3516 if(pClass->m_bSaveTransferCancelled) // was cancelled
3517 {
3518 pMinecraft->progressRenderer->progressStage(IDS_SAVE_TRANSFER_DOWNLOAD_CANCELLING);
3519 swprintf(wcTemp,app.GetString(IDS_SAVE_TRANSFER_DOWNLOAD_CANCELLING));
3520 m_wstrStageText=wcTemp;
3521 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
3522 }
3523 else
3524 {
3525 unsigned int uiProgress=(unsigned int)(((float)ulBytesReceived/float(UIScene_LoadOrJoinMenu::s_ulFileSize))*100.0f);
3526
3527 pMinecraft->progressRenderer->progressStagePercentage(uiProgress);
3528 swprintf(wcTemp,app.GetString(IDS_SAVETRANSFER_STAGE_GET_DATA),((float)(ulBytesReceived))/1024000.0f,((float)UIScene_LoadOrJoinMenu::s_ulFileSize)/1024000.0f);
3529 m_wstrStageText=wcTemp;
3530 pMinecraft->progressRenderer->progressStage( m_wstrStageText );
3531 }
3532
3533 return 0;
3534}
3535
3536void UIScene_LoadOrJoinMenu::CancelSaveTransferCallback(LPVOID lpParam)
3537{
3538 SaveTransferStateContainer* pClass = (SaveTransferStateContainer *) lpParam;
3539
3540 if(!pClass->m_bSaveTransferCancelled)
3541 {
3542 StorageManager.CancelSaveTransfer(UIScene_LoadOrJoinMenu::CancelSaveTransferCompleteCallback,pClass);
3543
3544 pClass->m_bSaveTransferCancelled=true;
3545 }
3546 //pClass->m_bSaveTransferInProgress=false;
3547}
3548
3549int UIScene_LoadOrJoinMenu::CancelSaveTransferCompleteCallback(LPVOID lpParam)
3550{
3551 SaveTransferStateContainer* pClass = (SaveTransferStateContainer *) lpParam;
3552 // change the state to idle to get the download thread to terminate
3553 pClass->m_eSaveTransferState=C4JStorage::eSaveTransfer_Idle;
3554 return 0;
3555}
3556
3557int UIScene_LoadOrJoinMenu::NeedSyncMessageReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
3558{
3559 UIScene_LoadOrJoinMenu *pClass = (UIScene_LoadOrJoinMenu *)pParam;
3560 LoadMenuInitData *params = (LoadMenuInitData *)pParam;
3561
3562 if( result == C4JStorage::EMessage_ResultAccept )
3563 {
3564 // navigate to the settings scene
3565 ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_LoadMenu, pClass->m_loadMenuInitData);
3566 }
3567 else
3568 {
3569 delete pClass->m_loadMenuInitData;
3570 pClass->m_bIgnoreInput = false;
3571 }
3572
3573 return 0;
3574}
3575
3576
3577#endif
3578
3579
3580#ifdef _XBOX_ONE
3581void UIScene_LoadOrJoinMenu::HandleDLCLicenseChange()
3582{
3583 // may have installed Halloween on this menu
3584 app.StartInstallDLCProcess(m_iPad);
3585}
3586#endif
3587
3588#if defined _XBOX_ONE || defined __ORBIS__
3589int UIScene_LoadOrJoinMenu::CopySaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
3590{
3591 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)pParam;
3592
3593 if(result==C4JStorage::EMessage_ResultAccept)
3594 {
3595
3596 LoadingInputParams *loadingParams = new LoadingInputParams();
3597 void *uniqueId = (LPVOID)pClass->GetCallbackUniqueId();
3598 loadingParams->func = &UIScene_LoadOrJoinMenu::CopySaveThreadProc;
3599 loadingParams->lpParam = uniqueId;
3600 loadingParams->waitForThreadToDelete = true;
3601
3602 UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData();
3603 completionData->bShowBackground=TRUE;
3604 completionData->bShowLogo=TRUE;
3605 completionData->type = e_ProgressCompletion_NavigateBackToScene;
3606 completionData->iPad = DEFAULT_XUI_MENU_USER;
3607 loadingParams->completionData = completionData;
3608
3609 loadingParams->cancelFunc=&UIScene_LoadOrJoinMenu::CancelCopySaveCallback;
3610 loadingParams->m_cancelFuncParam=uniqueId;
3611 loadingParams->cancelText=IDS_TOOLTIPS_CANCEL;
3612
3613 ui.NavigateToScene(iPad,eUIScene_FullscreenProgress, loadingParams);
3614 }
3615 else
3616 {
3617 pClass->m_bIgnoreInput=false;
3618 }
3619
3620 return 0;
3621}
3622
3623int UIScene_LoadOrJoinMenu::CopySaveThreadProc( LPVOID lpParameter )
3624{
3625 Minecraft *pMinecraft=Minecraft::GetInstance();
3626 pMinecraft->progressRenderer->progressStart(IDS_PROGRESS_COPYING_SAVE);
3627 pMinecraft->progressRenderer->progressStage( -1 );
3628
3629 ui.EnterCallbackIdCriticalSection();
3630 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParameter);
3631 if( pClass )
3632 {
3633 pClass->m_bCopying = true;
3634 pClass->m_bCopyingCancelled = false;
3635 ui.LeaveCallbackIdCriticalSection();
3636 // Copy save data takes two callbacks - one for completion, and one for progress. The progress callback also lets us cancel the operation, if we return false.
3637 StorageManager.CopySaveData(&pClass->m_pSaveDetails->SaveInfoA[pClass->m_iSaveListIndex - pClass->m_iDefaultButtonsC],UIScene_LoadOrJoinMenu::CopySaveDataReturned,UIScene_LoadOrJoinMenu::CopySaveDataProgress,lpParameter);
3638
3639 bool bContinue = true;
3640 do
3641 {
3642 Sleep(100);
3643 ui.EnterCallbackIdCriticalSection();
3644 pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParameter);
3645 if( pClass )
3646 {
3647 bContinue = pClass->m_bCopying;
3648 }
3649 else
3650 {
3651 bContinue = false;
3652 }
3653 ui.LeaveCallbackIdCriticalSection();
3654 } while( bContinue );
3655 }
3656 else
3657 {
3658 ui.LeaveCallbackIdCriticalSection();
3659 }
3660
3661 return 0;
3662}
3663
3664int UIScene_LoadOrJoinMenu::CopySaveDataReturned(LPVOID lpParam, bool success, C4JStorage::ESaveGameState stat)
3665{
3666 ui.EnterCallbackIdCriticalSection();
3667 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParam);
3668
3669 if(pClass)
3670 {
3671 if(success)
3672 {
3673 pClass->m_bCopying = false;
3674 // wipe the list and repopulate it
3675 pClass->m_iState=e_SavesRepopulateAfterDelete;
3676 ui.LeaveCallbackIdCriticalSection();
3677 }
3678 else
3679 {
3680#ifdef __ORBIS__
3681 UINT uiIDA[1];
3682 // you cancelled the save on exit after choosing exit and save? You go back to the Exit choices then.
3683 uiIDA[0]=IDS_OK;
3684
3685 if( stat == C4JStorage::ESaveGame_CopyCompleteFailLocalStorage )
3686 {
3687 ui.LeaveCallbackIdCriticalSection();
3688 ui.RequestErrorMessage(IDS_COPYSAVE_FAILED_TITLE, IDS_COPYSAVE_FAILED_LOCAL, uiIDA, 1, ProfileManager.GetPrimaryPad(), CopySaveErrorDialogFinishedCallback, lpParam);
3689 }
3690 else if( stat == C4JStorage::ESaveGame_CopyCompleteFailQuota )
3691 {
3692 ui.LeaveCallbackIdCriticalSection();
3693 ui.RequestErrorMessage(IDS_COPYSAVE_FAILED_TITLE, IDS_COPYSAVE_FAILED_QUOTA, uiIDA, 1, ProfileManager.GetPrimaryPad(), CopySaveErrorDialogFinishedCallback, lpParam);
3694 }
3695 else
3696 {
3697 pClass->m_bCopying = false;
3698 ui.LeaveCallbackIdCriticalSection();
3699 }
3700#else
3701 pClass->m_bCopying = false;
3702 ui.LeaveCallbackIdCriticalSection();
3703#endif
3704 }
3705 }
3706 else
3707 {
3708 ui.LeaveCallbackIdCriticalSection();
3709 }
3710 return 0;
3711}
3712
3713bool UIScene_LoadOrJoinMenu::CopySaveDataProgress(LPVOID lpParam, int percent)
3714{
3715 bool bContinue = false;
3716 ui.EnterCallbackIdCriticalSection();
3717 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParam);
3718 if( pClass )
3719 {
3720 bContinue = !pClass->m_bCopyingCancelled;
3721 }
3722 ui.LeaveCallbackIdCriticalSection();
3723 Minecraft *pMinecraft=Minecraft::GetInstance();
3724 pMinecraft->progressRenderer->progressStagePercentage(percent);
3725
3726 return bContinue;
3727}
3728
3729void UIScene_LoadOrJoinMenu::CancelCopySaveCallback(LPVOID lpParam)
3730{
3731 ui.EnterCallbackIdCriticalSection();
3732 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)lpParam);
3733 if( pClass )
3734 {
3735 pClass->m_bCopyingCancelled = true;
3736 }
3737 ui.LeaveCallbackIdCriticalSection();
3738}
3739
3740int UIScene_LoadOrJoinMenu::CopySaveErrorDialogFinishedCallback(void *pParam,int iPad,C4JStorage::EMessageResult result)
3741{
3742 ui.EnterCallbackIdCriticalSection();
3743 UIScene_LoadOrJoinMenu* pClass = (UIScene_LoadOrJoinMenu*)ui.GetSceneFromCallbackId((size_t)pParam);
3744 if( pClass )
3745 {
3746 pClass->m_bCopying = false;
3747 }
3748 ui.LeaveCallbackIdCriticalSection();
3749
3750 return 0;
3751}
3752
3753#endif // _XBOX_ONE