diff options
Diffstat (limited to 'Minecraft.Client/Common/XUI/XUI_TransferToXboxOne.cpp')
| -rw-r--r-- | Minecraft.Client/Common/XUI/XUI_TransferToXboxOne.cpp | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/Minecraft.Client/Common/XUI/XUI_TransferToXboxOne.cpp b/Minecraft.Client/Common/XUI/XUI_TransferToXboxOne.cpp new file mode 100644 index 00000000..5a2e67b4 --- /dev/null +++ b/Minecraft.Client/Common/XUI/XUI_TransferToXboxOne.cpp @@ -0,0 +1,569 @@ +#include "stdafx.h" +#include <xuiresource.h> +#include <xuiapp.h> +#include <assert.h> + +#include "XUI_Ctrl_4JList.h" +#include "XUI_Ctrl_4JIcon.h" +#include "XUI_LoadSettings.h" +#include "..\..\ProgressRenderer.h" +#include "XUI_TransferToXboxOne.h" + + +//---------------------------------------------------------------------------------- +// Performs initialization tasks - retrieves controls. +//---------------------------------------------------------------------------------- +HRESULT CScene_TransferToXboxOne::OnInit( XUIMessageInit* pInitData, BOOL& bHandled ) +{ + m_iX=-1; + m_params = (LoadMenuInitData *)pInitData->pvInitData; + + m_iPad=m_params->iPad; + + m_bRetrievingSaveInfo=false; + m_bIgnoreInput=false; + MapChildControls(); + + VOID *pObj; + XuiObjectFromHandle( m_SavesSlotList, &pObj ); + m_pSavesSlotList = (CXuiCtrl4JList *)pObj; + + m_pbImageData=NULL; + m_dwImageBytes=0; + + StorageManager.GetSaveCacheFileInfo(m_params->iSaveGameInfoIndex,m_XContentData); + StorageManager.GetSaveCacheFileInfo(m_params->iSaveGameInfoIndex,&m_pbImageData,&m_dwImageBytes); + + + m_SavesSlotListTimer.SetShow(TRUE); + + + XuiControlSetText(m_SavesSlotList,app.GetString(IDS_XBONE_SELECTSLOT)); + + // insert the current save slot names + m_MaxSlotC=app.m_uiTransferSlotC; + m_pSlotDataA = new SLOTDATA [m_MaxSlotC]; + ZeroMemory(m_pSlotDataA,sizeof(SLOTDATA)*m_MaxSlotC); + + + // saves will be called slot1 to slotx + // there will be a details file with the names and png of each slot + m_pbSlotListFile=NULL; + m_uiSlotListFileBytes=0; + + if(StorageManager.TMSPP_InFileList(C4JStorage::eGlobalStorage_TitleUser,m_iPad,L"XboxOne/SlotList")) + { + // there is a slot list file with details of the saves + C4JStorage::ETMSStatus status=StorageManager.TMSPP_ReadFile(m_iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,"XboxOne/SlotList",&CScene_TransferToXboxOne::TMSPPSlotListReturned,this); + m_iX=IDS_TOOLTIPS_CLEARSLOTS; + } + else + { + CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; + + ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); + + // create dummy slots + for(int i=0;i<m_MaxSlotC;i++) + { + memcpy(m_pSlotDataA[i].wchSaveTitle,app.GetString(IDS_XBONE_EMPTYSLOT),sizeof(WCHAR)*XCONTENT_MAX_DISPLAYNAME_LENGTH); + ListInfo.pwszText = app.GetString(IDS_XBONE_EMPTYSLOT); + ListInfo.fEnabled = TRUE; + ListInfo.iData = -1; + m_pSavesSlotList->AddData(ListInfo); + } + m_SavesSlotListTimer.SetShow(FALSE); + } + + + CXuiSceneBase::SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, m_iX, -1,-1,-1,-1,-1,-1,true); + + return S_OK; +} + +//---------------------------------------------------------------------------------- +// TMSPPSlotListReturned callback +//---------------------------------------------------------------------------------- +int CScene_TransferToXboxOne::TMSPPWriteReturned(LPVOID pParam,int iPad,int iUserData) +{ + CScene_TransferToXboxOne* pClass = (CScene_TransferToXboxOne *) pParam; + pClass->m_bWaitingForWrite=false; + + return 0; +} + +//---------------------------------------------------------------------------------- +// TMSPPSlotListReturned callback +//---------------------------------------------------------------------------------- +int CScene_TransferToXboxOne::TMSPPDeleteReturned(LPVOID pParam,int iPad,int iUserData) +{ + CScene_TransferToXboxOne* pClass = (CScene_TransferToXboxOne *) pParam; + pClass->m_SavesSlotListTimer.SetShow(FALSE); + pClass->m_bIgnoreInput=false; + + // update the slots + delete pClass->m_pbSlotListFile; + pClass->m_pbSlotListFile=NULL; + pClass->m_uiSlotListFileBytes=0; + pClass->m_pSavesSlotList->RemoveAllData(); + CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; + + ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); + // clear our slot info + ZeroMemory(pClass->m_pSlotDataA,sizeof(SLOTDATA)*pClass->m_MaxSlotC); + + for(int i=0;i<pClass->m_MaxSlotC;i++) + { + memcpy(pClass->m_pSlotDataA[i].wchSaveTitle,app.GetString(IDS_XBONE_EMPTYSLOT),sizeof(WCHAR)*XCONTENT_MAX_DISPLAYNAME_LENGTH); + ListInfo.pwszText = app.GetString(IDS_XBONE_EMPTYSLOT); + ListInfo.fEnabled = TRUE; + ListInfo.iData = -1; + pClass->m_pSavesSlotList->AddData(ListInfo); + } + + return 0; +} + +//---------------------------------------------------------------------------------- +// TMSPPSlotListReturned callback +//---------------------------------------------------------------------------------- +int CScene_TransferToXboxOne::TMSPPSlotListReturned(LPVOID pParam,int iPad,int iUserData,C4JStorage::PTMSPP_FILEDATA pFileData, LPCSTR szFilename) +{ + CScene_TransferToXboxOne* pClass = (CScene_TransferToXboxOne *) pParam; + unsigned int uiSlotListFileSlots=*((unsigned int *)pFileData->pbData); + pClass->m_pbSlotListFile=pFileData->pbData; + pClass->m_uiSlotListFileBytes=pFileData->dwSize; + + // clear our slot info + ZeroMemory(pClass->m_pSlotDataA,sizeof(SLOTDATA)*pClass->m_MaxSlotC); + // set the empty slot strings + for(int i=0;i<pClass->m_MaxSlotC;i++) + { + memcpy(pClass->m_pSlotDataA[i].wchSaveTitle,app.GetString(IDS_XBONE_EMPTYSLOT),sizeof(WCHAR)*XCONTENT_MAX_DISPLAYNAME_LENGTH); + } + // update our slot info with the data from the file - might have less slots + unsigned int uiNewSlotsC=(pClass->m_MaxSlotC<uiSlotListFileSlots)?pClass->m_MaxSlotC:uiSlotListFileSlots; + memcpy(pClass->m_pSlotDataA,pClass->m_pbSlotListFile + sizeof(unsigned int),sizeof(SLOTDATA)*uiNewSlotsC); + + CXuiCtrl4JList::LIST_ITEM_INFO ListInfo; + + ZeroMemory(&ListInfo,sizeof(CXuiCtrl4JList::LIST_ITEM_INFO)); + PBYTE pbImageData=pClass->m_pbSlotListFile + sizeof(unsigned int) + sizeof(SLOTDATA)*uiSlotListFileSlots; + + // fill out the slot info + for(int i=0;i<pClass->m_MaxSlotC;i++) + { + if(i<uiNewSlotsC) + { + ListInfo.pwszText = pClass->m_pSlotDataA[i].wchSaveTitle; + ListInfo.fEnabled = TRUE; + ListInfo.iData = -1; + pClass->m_pSavesSlotList->AddData(ListInfo); + + if(pClass->m_pSlotDataA[i].uiImageLength!=0) + { + XuiCreateTextureBrushFromMemory(pbImageData,pClass->m_pSlotDataA[i].uiImageLength,&pClass->m_hXuiBrush); + pClass->m_pSavesSlotList->UpdateGraphic(i,pClass->m_hXuiBrush); + // increment the image data pointer + pbImageData+=pClass->m_pSlotDataA[i].uiImageLength; + } + } + else + { + // make it blank + ListInfo.pwszText = app.GetString(IDS_XBONE_EMPTYSLOT); + ListInfo.fEnabled = TRUE; + ListInfo.iData = -1; + pClass->m_pSavesSlotList->AddData(ListInfo); + } + } + pClass->m_SavesSlotListTimer.SetShow(FALSE); + return 0; + +} + +//---------------------------------------------------------------------------------- +// Handler for OnDestroy +//---------------------------------------------------------------------------------- +HRESULT CScene_TransferToXboxOne::OnDestroy() +{ + return S_OK; +} + +//---------------------------------------------------------------------------------- +// Handler for the button press message. +//---------------------------------------------------------------------------------- +HRESULT CScene_TransferToXboxOne::OnNotifyPressEx(HXUIOBJ hObjPressed, XUINotifyPress* pNotifyPressData, BOOL& rfHandled) +{ + if(m_bIgnoreInput) return S_OK; + + // if we're retrieving save info, ignore key presses + if(m_bRetrievingSaveInfo) + { + return S_OK; + } + + // This assumes all buttons can only be pressed with the A button + ui.AnimateKeyPress(pNotifyPressData->UserIndex, VK_PAD_A); + + if(hObjPressed==m_SavesSlotList) + { + m_bIgnoreInput=true; + + // update the info in the SlotList file + CXuiControl pItem; + int iIndex; + + // get the selected item + iIndex=m_SavesSlotList.GetCurSel(&pItem); + + // check if there is a save there + + CXuiCtrl4JList::LIST_ITEM_INFO info = m_pSavesSlotList->GetData(iIndex); + if(info.pwszImage!=NULL) + { + // we have a save here + // Are you sure, etc. + } + + // update the data + memcpy(m_pSlotDataA[iIndex].wchSaveTitle,m_XContentData.szDisplayName,sizeof(WCHAR)*XCONTENT_MAX_DISPLAYNAME_LENGTH); + m_pSavesSlotList->UpdateText(iIndex,m_pSlotDataA[iIndex].wchSaveTitle); + + // if there is no thumbnail, retrieve the default one from the file. + // Don't delete the image data after creating the xuibrush, since we'll use it in the rename of the save + bool bHostOptionsRead = false; + unsigned int uiHostOptions = 0; + + XuiCreateTextureBrushFromMemory(m_pbImageData,m_dwImageBytes,&m_hXuiBrush); + m_pSavesSlotList->UpdateGraphic(iIndex,m_hXuiBrush); + + m_pSlotDataA[iIndex].uiImageLength=m_dwImageBytes; + + m_bIgnoreInput=false; + + // finished so navigate back + //app.NavigateBack(XUSER_INDEX_ANY); + BuildSlotFile(iIndex,m_pbImageData,m_dwImageBytes); + } + + return S_OK; +} + +HRESULT CScene_TransferToXboxOne::BuildSlotFile(int iIndexBeingUpdated,PBYTE pbImageData,DWORD dwImageBytes ) +{ + SLOTDATA *pCurrentSlotData=NULL; + PBYTE pbCurrentSlotDataPtr=NULL; + // there may be no slot file yet + if(m_pbSlotListFile!=NULL) + { + pCurrentSlotData=(SLOTDATA *)(m_pbSlotListFile+sizeof(unsigned int)); + pbCurrentSlotDataPtr=m_pbSlotListFile + sizeof(unsigned int) + sizeof(SLOTDATA)*m_MaxSlotC; + } + + m_uiSlotID=iIndexBeingUpdated; + + // memory required - first int is the number of slots in this file, in case that changes later + unsigned int uiBytesRequired=sizeof(unsigned int) + sizeof(SLOTDATA)*m_MaxSlotC; + for(int i=0;i<m_MaxSlotC;i++) + { + if(i==iIndexBeingUpdated) + { + uiBytesRequired+=dwImageBytes; + } + else + { + uiBytesRequired+=m_pSlotDataA[i].uiImageLength; + } + } + + PBYTE pbNewSlotFileData= new BYTE [uiBytesRequired]; + *((unsigned int *)pbNewSlotFileData)=m_MaxSlotC; + PBYTE pbNewSlotFileDataSlots=pbNewSlotFileData + sizeof(unsigned int); + PBYTE pbNewSlotImageDataPtr=pbNewSlotFileData + sizeof(unsigned int) + sizeof(SLOTDATA)*m_MaxSlotC; + SLOTDATA *pNewSlotData=(SLOTDATA *)pbNewSlotFileDataSlots; + + // copy the slot info into the new memory, just after the first int + memcpy(pbNewSlotFileDataSlots,m_pSlotDataA,sizeof(SLOTDATA)*m_MaxSlotC); + + for(int i=0;i<m_MaxSlotC;i++) + { + if(i==iIndexBeingUpdated) + { + memcpy(pbNewSlotImageDataPtr,pbImageData,dwImageBytes); + pbNewSlotImageDataPtr+=dwImageBytes; + // update the fields + pNewSlotData[i].uiImageLength=dwImageBytes; + // save title is already correct + } + else + { + if(pbCurrentSlotDataPtr!=NULL) + { + memcpy(pbNewSlotImageDataPtr,pbCurrentSlotDataPtr,pCurrentSlotData[i].uiImageLength); + pbNewSlotImageDataPtr+=pCurrentSlotData[i].uiImageLength; + } + // fields are already correct + } + + // move to the next image data in the current slot file + if(pbCurrentSlotDataPtr!=NULL) + { + pbCurrentSlotDataPtr+=pCurrentSlotData[i].uiImageLength; + } + } + + // free the previous file data and the current file data + delete m_pbSlotListFile; + + // reset the pointer until we have the exit from this scene running + m_pbSlotListFile = pbNewSlotFileData; + m_uiSlotListFileBytes = uiBytesRequired; + m_pSlotDataA = (SLOTDATA *)pbNewSlotFileDataSlots; + + LoadingInputParams *loadingParams = new LoadingInputParams(); + loadingParams->func = &CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc; + loadingParams->lpParam = (LPVOID)this; + + UIFullscreenProgressCompletionData *completionData = new UIFullscreenProgressCompletionData(); + completionData->bShowBackground=TRUE; + completionData->bShowLogo=TRUE; + completionData->iPad = m_iPad; + completionData->type = e_ProgressCompletion_NavigateBackToScene; + completionData->scene = eUIScene_LoadMenu; + loadingParams->completionData = completionData; + + app.NavigateToScene(m_iPad,eUIScene_FullscreenProgress, loadingParams); + + return S_OK; +} + +int CScene_TransferToXboxOne::UploadSaveForXboxOneThreadProc( LPVOID lpParameter ) +{ + HRESULT hr = S_OK; + char szFilename[32]; + CScene_TransferToXboxOne* pClass = (CScene_TransferToXboxOne *) lpParameter; + Minecraft *pMinecraft = Minecraft::GetInstance(); + unsigned int uiComplete=0; + pClass->m_bWaitingForWrite=true; + pMinecraft->progressRenderer->progressStart(IDS_XBONE_UPLOAD_SAVE_TITLE); + pMinecraft->progressRenderer->progressStage( IDS_XBONE_UPLOAD_METADATA ); + // now write the new slot data file to global storage, and then write the save data + C4JStorage::ETMSStatus eStatus=StorageManager.TMSPP_WriteFile(pClass->m_iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,"XboxOne/SlotList",(PCHAR) pClass->m_pbSlotListFile, pClass->m_uiSlotListFileBytes, + &CScene_TransferToXboxOne::TMSPPWriteReturned,lpParameter, 0); + + if(eStatus!=C4JStorage::ETMSStatus_WriteInProgress) + { + // failed + pClass->m_bWaitingForWrite=false; + } + else + { + // loop waiting for the write to complete + uiComplete=0; + while(pClass->m_bWaitingForWrite && (hr == S_OK)) + { + Sleep(50); + uiComplete++; + if(uiComplete>100) uiComplete=100; + + pMinecraft->progressRenderer->progressStagePercentage(uiComplete); + + if(app.GetChangingSessionType()) + { + // 4J Stu - This causes the fullscreenprogress scene to ignore the action it was given + hr = ERROR_CANCELLED; + } + } + + if(hr!=S_OK) return -1; + + // finish the bar + for(int i=uiComplete;i<100;i++) + { + Sleep(5); + pMinecraft->progressRenderer->progressStagePercentage(i); + } + + + // now upload the save data + pMinecraft->progressRenderer->progressStage( IDS_XBONE_UPLOAD_SAVE ); + + // write the save file, and increment the progress percentage + pMinecraft->progressRenderer->progressStagePercentage(25); + pClass->m_bSaveDataReceived=false; + C4JStorage::ELoadGameStatus eLoadStatus=StorageManager.LoadSaveData(&pClass->m_XContentData,CScene_TransferToXboxOne::LoadSaveDataReturned,lpParameter); + + // sleep until we have the data + while(pClass->m_bSaveDataReceived==false) + { + Sleep(50); + } + + // write the save to user TMS + + // break the file up into 256K chunks + unsigned int uiChunkSize=262144; + unsigned int uiBytesLeft=pClass->m_uiStorageLength; + C4JStorage::ETMSStatus eStatus; + // max file size would be 100*256K + unsigned int uiPercentageChunk=100/(pClass->m_uiStorageLength/uiChunkSize); + uiComplete=0; + + if(uiPercentageChunk==0) uiPercentageChunk=1; + + for(int i=0;i<(pClass->m_uiStorageLength/uiChunkSize)+1;i++) + { + sprintf( szFilename, "XboxOne/Slot%.2d%.2d", pClass->m_uiSlotID,i ); + PCHAR pchData=((PCHAR)pClass->m_pvSaveMem)+i*uiChunkSize; + + pClass->m_bWaitingForWrite=true; + if(uiBytesLeft>=uiChunkSize) + { + eStatus=StorageManager.TMSPP_WriteFile(pClass->m_iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,szFilename,pchData, uiChunkSize, + &CScene_TransferToXboxOne::TMSPPWriteReturned,lpParameter, 0); + uiBytesLeft-=uiChunkSize; + } + else + { + // last bit of the file to upload is less than uiChunkSize + eStatus=StorageManager.TMSPP_WriteFile(pClass->m_iPad,C4JStorage::eGlobalStorage_TitleUser,C4JStorage::TMS_FILETYPE_BINARY,C4JStorage::TMS_UGCTYPE_NONE,szFilename,pchData, uiBytesLeft, + &CScene_TransferToXboxOne::TMSPPWriteReturned,lpParameter, 0); + } + + // wait until + if(eStatus!=C4JStorage::ETMSStatus_WriteInProgress) + { + // failed + pClass->m_bWaitingForWrite=false; + } + else + { + // loop waiting for the write to complete + while(pClass->m_bWaitingForWrite && (hr == S_OK)) + { + Sleep(50); + } + uiComplete+=uiPercentageChunk; + if(uiComplete>100) uiComplete=100; + + // update the progress + pMinecraft->progressRenderer->progressStagePercentage(uiComplete); + } + } + + + + delete pClass->m_pvSaveMem; + } + return hr; +} + +int CScene_TransferToXboxOne::LoadSaveDataReturned(void *pParam,bool bContinue) +{ + CScene_TransferToXboxOne* pClass = (CScene_TransferToXboxOne*)pParam; + + if(bContinue==true) + { + unsigned int uiFileSize = StorageManager.GetSaveSize(); + pClass->m_pvSaveMem = new BYTE [uiFileSize]; + pClass->m_uiStorageLength=0; + + StorageManager.GetSaveData( pClass->m_pvSaveMem, &pClass->m_uiStorageLength ); + + pClass->m_bSaveDataReceived=true; + } + + return 0; +} + +HRESULT CScene_TransferToXboxOne::OnKeyDown(XUIMessageInput* pInputData, BOOL& rfHandled) +{ + if(m_bIgnoreInput) return S_OK; + + // if we're retrieving save info, ignore key presses + if(m_bRetrievingSaveInfo) + { + return S_OK; + } + + ui.AnimateKeyPress(pInputData->UserIndex, pInputData->dwKeyCode); + + HRESULT hr = S_OK; + + // Explicitly handle B button presses + switch(pInputData->dwKeyCode) + { + case VK_PAD_B: + case VK_ESCAPE: + + app.NavigateBack(XUSER_INDEX_ANY); + rfHandled = TRUE; + break; + case VK_PAD_X: + // wipe the save slots + if(m_pbSlotListFile!=NULL) + { + m_SavesSlotListTimer.SetShow(TRUE); + m_bIgnoreInput=true; + + C4JStorage::ETMSStatus eStatus=StorageManager.TMSPP_DeleteFile(m_iPad,"XboxOne/SlotList",C4JStorage::TMS_FILETYPE_BINARY,&CScene_TransferToXboxOne::TMSPPDeleteReturned,this, 0); + + } + + break; + } + + return hr; +} + +HRESULT CScene_TransferToXboxOne::OnNotifySelChanged(HXUIOBJ hObjSource, XUINotifySelChanged *pNotifySelChangedData, BOOL& bHandled) +{ + + //if(m_bReady) + { + CXuiSceneBase::PlayUISFX(eSFX_Focus); + } + + return S_OK; +} + + +HRESULT CScene_TransferToXboxOne::OnTransitionStart( XUIMessageTransition *pTransition, BOOL& bHandled ) +{ + //if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY ) return S_OK; + + if(pTransition->dwTransAction==XUI_TRANSITION_ACTION_DESTROY || + pTransition->dwTransType == XUI_TRANSITION_FROM || pTransition->dwTransType == XUI_TRANSITION_BACKFROM) + { + // 4J Stu - We may have had to unload our font renderer in this scene if one of the save files + // uses characters not in our font (eg asian chars) so restore our font renderer + // This will not do anything if our font renderer is already loaded + app.OverrideFontRenderer(true,true); + } + + return S_OK; +} + +HRESULT CScene_TransferToXboxOne::OnFontRendererChange() +{ + // update the tooltips + CXuiSceneBase::SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, m_iX, -1,-1,-1,-1,-1,-1,true); + + return S_OK; +} + +HRESULT CScene_TransferToXboxOne::OnNotifySetFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled) +{ + // update the tooltips + CXuiSceneBase::SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, m_iX, -1,-1,-1,-1,-1,-1,true); + + return S_OK; +} + +HRESULT CScene_TransferToXboxOne::OnNotifyKillFocus(HXUIOBJ hObjSource, XUINotifyFocus *pNotifyFocusData, BOOL& bHandled) +{ + return S_OK; +} + + |
