From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- .../Common/UI/UIScene_InGameSaveManagementMenu.cpp | 497 +++++++++++++++++++++ 1 file changed, 497 insertions(+) create mode 100644 Minecraft.Client/Common/UI/UIScene_InGameSaveManagementMenu.cpp (limited to 'Minecraft.Client/Common/UI/UIScene_InGameSaveManagementMenu.cpp') diff --git a/Minecraft.Client/Common/UI/UIScene_InGameSaveManagementMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InGameSaveManagementMenu.cpp new file mode 100644 index 00000000..b0dbc59f --- /dev/null +++ b/Minecraft.Client/Common/UI/UIScene_InGameSaveManagementMenu.cpp @@ -0,0 +1,497 @@ +#include "stdafx.h" +#include "UI.h" +#include "UIScene_InGameSaveManagementMenu.h" + +#if defined(__ORBIS__) || defined(__PSVITA__) +#include +#endif + +int UIScene_InGameSaveManagementMenu::LoadSaveDataThumbnailReturned(LPVOID lpParam,PBYTE pbThumbnail,DWORD dwThumbnailBytes) +{ + UIScene_InGameSaveManagementMenu *pClass= (UIScene_InGameSaveManagementMenu *)lpParam; + + app.DebugPrintf("Received data for save thumbnail\n"); + + if(pbThumbnail && dwThumbnailBytes) + { + pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData = new BYTE[dwThumbnailBytes]; + memcpy(pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData, pbThumbnail, dwThumbnailBytes); + pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].dwThumbnailSize = dwThumbnailBytes; + } + else + { + pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].pbThumbnailData = NULL; + pClass->m_saveDetails[pClass->m_iRequestingThumbnailId].dwThumbnailSize = 0; + app.DebugPrintf("Save thumbnail data is NULL, or has size 0\n"); + } + pClass->m_bSaveThumbnailReady = true; + + return 0; +} + +UIScene_InGameSaveManagementMenu::UIScene_InGameSaveManagementMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene(iPad, parentLayer) +{ + // Setup all the Iggy references we need for this scene + initialiseMovie(); + + m_iRequestingThumbnailId = 0; + m_iSaveInfoC=0; + m_bIgnoreInput = false; + m_iState=e_SavesIdle; + //m_bRetrievingSaveInfo=false; + + m_buttonListSaves.init(eControl_SavesList); + + m_labelSavesListTitle.init( app.GetString(IDS_SAVE_INCOMPLETE_DELETE_SAVES) ); + m_controlSavesTimer.setVisible( true ); + + +#if defined(_XBOX_ONE) || defined(__ORBIS__) + m_spaceIndicatorSaves.init(L"",eControl_SpaceIndicator,0, (4LL *1024LL * 1024LL * 1024LL) ); +#endif + m_bUpdateSaveSize = false; + + m_bAllLoaded = false; + m_bRetrievingSaveThumbnails = false; + m_bSaveThumbnailReady = false; + m_bExitScene=false; + m_pSaveDetails=NULL; + m_bSavesDisplayed=false; + m_saveDetails = NULL; + m_iSaveDetailsCount = 0; + +#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) || defined(_DURANGO) + // Always clear the saves when we enter this menu + StorageManager.ClearSavesInfo(); +#endif + + // 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 + if(app.StartInstallDLCProcess(m_iPad)==true || app.DLCInstallPending()) + { + // 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 + m_bIgnoreInput = true; + } + else + { + Initialise(); + } + +#ifdef __PSVITA__ + if(CGameNetworkManager::usingAdhocMode() && SQRNetworkManager_AdHoc_Vita::GetAdhocStatus()) + { + g_NetworkManager.startAdhocMatching(); // create the client matching context and clear out the friends list + } + +#endif + + // 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. + if( !m_bIgnoreInput) + { + app.m_dlcManager.checkForCorruptDLCAndAlert(); + } + + parentLayer->addComponent(iPad,eUIComponent_MenuBackground); +} + + +UIScene_InGameSaveManagementMenu::~UIScene_InGameSaveManagementMenu() +{ + m_parentLayer->removeComponent(eUIComponent_MenuBackground); + + if(m_saveDetails) + { + for(int i = 0; i < m_iSaveDetailsCount; ++i) + { + delete m_saveDetails[i].pbThumbnailData; + } + delete [] m_saveDetails; + } + app.LeaveSaveNotificationSection(); + StorageManager.SetSaveDisabled(false); + StorageManager.ContinueIncompleteOperation(); +} + +void UIScene_InGameSaveManagementMenu::updateTooltips() +{ + int iA = -1; + if( m_bSavesDisplayed && m_iSaveDetailsCount > 0) + { + iA = IDS_TOOLTIPS_DELETESAVE; + } + ui.SetTooltips( m_parentLayer->IsFullscreenGroup()?XUSER_INDEX_ANY:m_iPad, iA, IDS_SAVE_INCOMPLETE_RETRY_SAVING); +} + +// +void UIScene_InGameSaveManagementMenu::Initialise() +{ + m_iSaveListIndex = 0; + + // Check if we're in the trial version + if(ProfileManager.IsFullVersion()==false) + { + } + else if(StorageManager.GetSaveDisabled()) + { + GetSaveInfo(); + } + else + { + // 4J-PB - we need to check that there is enough space left to create a copy of the save (for a rename) + bool bCanRename = StorageManager.EnoughSpaceForAMinSaveGame(); + + GetSaveInfo(); + } + + m_bIgnoreInput=false; +} + +void UIScene_InGameSaveManagementMenu::handleReload() +{ + m_bIgnoreInput = false; + m_iRequestingThumbnailId = 0; + m_bAllLoaded=false; + m_bRetrievingSaveThumbnails=false; + m_bSavesDisplayed=false; + m_iSaveInfoC=0; +} + +void UIScene_InGameSaveManagementMenu::handleGainFocus(bool navBack) +{ + UIScene::handleGainFocus(navBack); + + updateTooltips(); + + if(navBack) + { + // re-enable button presses + m_bIgnoreInput=false; + } +} + +wstring UIScene_InGameSaveManagementMenu::getMoviePath() +{ + return L"SaveMenu"; +} + +void UIScene_InGameSaveManagementMenu::tick() +{ + UIScene::tick(); + + if(m_bExitScene) // navigate forward or back + { + if(!m_bRetrievingSaveThumbnails) + { + // need to wait for any callback retrieving thumbnail to complete + navigateBack(); + } + } + // Stop loading thumbnails if we navigate forwards + if(hasFocus(m_iPad)) + { + if(m_bUpdateSaveSize) + { + m_spaceIndicatorSaves.selectSave(m_iSaveListIndex); + m_bUpdateSaveSize = false; + } + + // Display the saves if we have them + if(!m_bSavesDisplayed) + { + m_pSaveDetails=StorageManager.ReturnSavesInfo(); + if(m_pSaveDetails!=NULL) + { + m_spaceIndicatorSaves.reset(); + + m_bSavesDisplayed=true; + + if(m_saveDetails!=NULL) + { + for(unsigned int i = 0; i < m_pSaveDetails->iSaveC; ++i) + { + if(m_saveDetails[i].pbThumbnailData!=NULL) + { + delete m_saveDetails[i].pbThumbnailData; + } + } + delete m_saveDetails; + } + m_saveDetails = new SaveListDetails[m_pSaveDetails->iSaveC]; + + m_iSaveDetailsCount = m_pSaveDetails->iSaveC; + for(unsigned int i = 0; i < m_pSaveDetails->iSaveC; ++i) + { +#if defined(_XBOX_ONE) + m_spaceIndicatorSaves.addSave( m_pSaveDetails->SaveInfoA[i].totalSize ); +#elif defined(__ORBIS__) + m_spaceIndicatorSaves.addSave( m_pSaveDetails->SaveInfoA[i].blocksUsed * (32 * 1024) ); +#endif +#ifdef _DURANGO + m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, L""); + + m_saveDetails[i].saveId = i; + memcpy(m_saveDetails[i].UTF16SaveName, m_pSaveDetails->SaveInfoA[i].UTF16SaveTitle, 128); + memcpy(m_saveDetails[i].UTF16SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH); +#else + m_buttonListSaves.addItem(m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, L""); + + m_saveDetails[i].saveId = i; + memcpy(m_saveDetails[i].UTF8SaveName, m_pSaveDetails->SaveInfoA[i].UTF8SaveTitle, 128); + memcpy(m_saveDetails[i].UTF8SaveFilename, m_pSaveDetails->SaveInfoA[i].UTF8SaveFilename, MAX_SAVEFILENAME_LENGTH); +#endif + } + m_controlSavesTimer.setVisible( false ); + + // set focus on the first button + + } + } + + if(!m_bExitScene && m_bSavesDisplayed && !m_bRetrievingSaveThumbnails && !m_bAllLoaded) + { + if( m_iRequestingThumbnailId < (m_buttonListSaves.getItemCount() )) + { + m_bRetrievingSaveThumbnails = true; + app.DebugPrintf("Requesting the first thumbnail\n"); + // set the save to load + PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo(); + C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this); + + if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail) + { + // something went wrong + m_bRetrievingSaveThumbnails=false; + m_bAllLoaded = true; + } + } + } + else if (m_bSavesDisplayed && m_bSaveThumbnailReady) + { + m_bSaveThumbnailReady = false; + + // check we're not waiting to exit the scene + if(!m_bExitScene) + { + // convert to utf16 + uint16_t u16Message[MAX_SAVEFILENAME_LENGTH]; +#ifdef _DURANGO + // Already utf16 on durango + memcpy(u16Message, m_saveDetails[m_iRequestingThumbnailId].UTF16SaveFilename, MAX_SAVEFILENAME_LENGTH); +#elif defined(_WINDOWS64) + int result = ::MultiByteToWideChar( + CP_UTF8, // convert from UTF-8 + MB_ERR_INVALID_CHARS, // error on invalid chars + m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename, // source UTF-8 string + MAX_SAVEFILENAME_LENGTH, // total length of source UTF-8 string, + // in CHAR's (= bytes), including end-of-string \0 + (wchar_t *)u16Message, // destination buffer + MAX_SAVEFILENAME_LENGTH // size of destination buffer, in WCHAR's + ); +#else +#ifdef __PS3 + size_t srcmax,dstmax; +#else + uint32_t srcmax,dstmax; + uint32_t srclen,dstlen; +#endif + srcmax=MAX_SAVEFILENAME_LENGTH; + dstmax=MAX_SAVEFILENAME_LENGTH; + +#if defined(__PS3__) + L10nResult lres= UTF8stoUTF16s((uint8_t *)m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename,&srcmax,u16Message,&dstmax); +#else + SceCesUcsContext context; + sceCesUcsContextInit(&context); + + sceCesUtf8StrToUtf16Str(&context, (uint8_t *)m_saveDetails[m_iRequestingThumbnailId].UTF8SaveFilename,srcmax,&srclen,u16Message,dstmax,&dstlen); +#endif +#endif + if( m_saveDetails[m_iRequestingThumbnailId].pbThumbnailData ) + { + registerSubstitutionTexture((wchar_t *)u16Message,m_saveDetails[m_iRequestingThumbnailId].pbThumbnailData,m_saveDetails[m_iRequestingThumbnailId].dwThumbnailSize); + } + m_buttonListSaves.setTextureName(m_iRequestingThumbnailId, (wchar_t *)u16Message); + + ++m_iRequestingThumbnailId; + if( m_iRequestingThumbnailId < (m_buttonListSaves.getItemCount() )) + { + app.DebugPrintf("Requesting another thumbnail\n"); + // set the save to load + PSAVE_DETAILS pSaveDetails=StorageManager.ReturnSavesInfo(); + C4JStorage::ESaveGameState eLoadStatus=StorageManager.LoadSaveDataThumbnail(&pSaveDetails->SaveInfoA[(int)m_iRequestingThumbnailId],&LoadSaveDataThumbnailReturned,this); + if(eLoadStatus!=C4JStorage::ESaveGame_GetSaveThumbnail) + { + // something went wrong + m_bRetrievingSaveThumbnails=false; + m_bAllLoaded = true; + } + } + else + { + m_bRetrievingSaveThumbnails = false; + m_bAllLoaded = true; + } + } + else + { + // stop retrieving thumbnails, and exit + m_bRetrievingSaveThumbnails = false; + } + } + } + + switch(m_iState) + { + case e_SavesIdle: + break; + case e_SavesRepopulateAfterDelete: + m_bIgnoreInput = false; + m_iRequestingThumbnailId = 0; + m_bAllLoaded=false; + m_bRetrievingSaveThumbnails=false; + m_bSavesDisplayed=false; + m_iSaveInfoC=0; + m_buttonListSaves.clearList(); + //StorageManager.ClearSavesInfo(); + //GetSaveInfo(); + m_iState=e_SavesIdle; + break; + } +} + +void UIScene_InGameSaveManagementMenu::GetSaveInfo( ) +{ + unsigned int uiSaveC=0; + + // This will return with the number retrieved in uiSaveC + + // clear the saves list + m_bSavesDisplayed = false; // we're blocking the exit from this scene until complete + m_buttonListSaves.clearList(); + m_iSaveInfoC=0; + m_controlSavesTimer.setVisible(true); + + m_pSaveDetails=StorageManager.ReturnSavesInfo(); + if(m_pSaveDetails==NULL) + { + C4JStorage::ESaveGameState eSGIStatus= StorageManager.GetSavesInfo(m_iPad,NULL,this,"save"); + } + + + return; +} + +void UIScene_InGameSaveManagementMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) +{ + if(m_bIgnoreInput) return; + + // if we're retrieving save info, ignore key presses + if(!m_bSavesDisplayed) return; + + ui.AnimateKeyPress(m_iPad, key, repeat, pressed, released); + + switch(key) + { + case ACTION_MENU_CANCEL: + if(pressed) + { +#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) + m_bExitScene=true; +#else + navigateBack(); +#endif + handled = true; + } + break; + case ACTION_MENU_OK: +#ifdef __ORBIS__ + case ACTION_MENU_TOUCHPAD_PRESS: +#endif + case ACTION_MENU_UP: + case ACTION_MENU_DOWN: + case ACTION_MENU_PAGEUP: + case ACTION_MENU_PAGEDOWN: + sendInputToMovie(key, repeat, pressed, released); + handled = true; + break; + } +} + +void UIScene_InGameSaveManagementMenu::handleInitFocus(F64 controlId, F64 childId) +{ + app.DebugPrintf(app.USER_SR, "UIScene_InGameSaveManagementMenu::handleInitFocus - %d , %d\n", (int)controlId, (int)childId); +} + +void UIScene_InGameSaveManagementMenu::handleFocusChange(F64 controlId, F64 childId) +{ + app.DebugPrintf(app.USER_SR, "UIScene_InGameSaveManagementMenu::handleFocusChange - %d , %d\n", (int)controlId, (int)childId); + m_iSaveListIndex = childId; + if(m_bSavesDisplayed) m_bUpdateSaveSize = true; + updateTooltips(); +} + +void UIScene_InGameSaveManagementMenu::handlePress(F64 controlId, F64 childId) +{ + switch((int)controlId) + { + case eControl_SavesList: + { + m_bIgnoreInput = true; + + // delete the save game + // Have to ask the player if they are sure they want to delete this game + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestMessageBox(IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2,m_iPad,&UIScene_InGameSaveManagementMenu::DeleteSaveDialogReturned,this, app.GetStringTable(),NULL,0,true); + + ui.PlayUISFX(eSFX_Press); + break; + } + } +} + +int UIScene_InGameSaveManagementMenu::DeleteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) +{ + UIScene_InGameSaveManagementMenu* pClass = (UIScene_InGameSaveManagementMenu*)pParam; + // results switched for this dialog + + if(result==C4JStorage::EMessage_ResultDecline) + { + if(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) + { + pClass->m_bIgnoreInput=false; + } + else + { + StorageManager.DeleteSaveData(&pClass->m_pSaveDetails->SaveInfoA[pClass->m_iSaveListIndex],UIScene_InGameSaveManagementMenu::DeleteSaveDataReturned,pClass); + pClass->m_controlSavesTimer.setVisible( true ); + } + } + else + { + pClass->m_bIgnoreInput=false; + } + + return 0; +} + +int UIScene_InGameSaveManagementMenu::DeleteSaveDataReturned(LPVOID lpParam,bool bRes) +{ + UIScene_InGameSaveManagementMenu* pClass = (UIScene_InGameSaveManagementMenu*)lpParam; + + if(bRes) + { + // wipe the list and repopulate it + pClass->m_iState=e_SavesRepopulateAfterDelete; + } + else pClass->m_bIgnoreInput=false; + + pClass->updateTooltips(); + + return 0; +} + +bool UIScene_InGameSaveManagementMenu::hasFocus(int iPad) +{ + return bHasFocus && (iPad == m_iPad || m_iPad == XUSER_INDEX_ANY); +} \ No newline at end of file -- cgit v1.2.3