mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-25 12:53:36 +00:00
2741 lines
101 KiB
C++
2741 lines
101 KiB
C++
#include "../../Minecraft.World/Platform/stdafx.h"
|
|
#include <xuiresource.h>
|
|
#include <xuiapp.h>
|
|
#include <thread>
|
|
#include <chrono>
|
|
#include <assert.h>
|
|
#include "../../Minecraft.World/Util/StringHelpers.h"
|
|
#include "../Tutorial/TutorialMode.h"
|
|
#include "../../Minecraft.World/IO/Files/ConsoleSaveFileIO.h"
|
|
#include "../../Minecraft.Client/Player/LocalPlayer.h"
|
|
#include "../../Minecraft.Client/Minecraft.h"
|
|
#include "../../Minecraft.Client/Rendering/EntityRenderers/ProgressRenderer.h"
|
|
#include "../../Minecraft.World/Util/AABB.h"
|
|
#include "../../Minecraft.World/Util/Vec3.h"
|
|
#include "../../Minecraft.World/Util/ArrayWithLength.h"
|
|
#include "../../Minecraft.World/IO/Files/File.h"
|
|
#include "../../Minecraft.World/IO/Streams/InputOutputStream.h"
|
|
#include "XUI_Ctrl_4JList.h"
|
|
#include "XUI_Ctrl_4JIcon.h"
|
|
#include "XUI_LoadSettings.h"
|
|
#include "XUI_MultiGameInfo.h"
|
|
#include "XUI_MultiGameJoinLoad.h"
|
|
#include "XUI_MultiGameCreate.h"
|
|
#include "../../Minecraft.Client/MinecraftServer.h"
|
|
#include "../../Minecraft.Client/GameState/Options.h"
|
|
|
|
#include "../GameRules/LevelGenerationOptions.h"
|
|
#include "../../Minecraft.Client/Textures/Packs/TexturePackRepository.h"
|
|
#include "../../Minecraft.Client/Textures/Packs/TexturePack.h"
|
|
#include "../../Minecraft.World/Level/Storage/LevelSettings.h"
|
|
|
|
#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID 3
|
|
#define CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME 100
|
|
|
|
//----------------------------------------------------------------------------------
|
|
// Performs initialization tasks - retrieves controls.
|
|
//----------------------------------------------------------------------------------
|
|
HRESULT CScene_MultiGameJoinLoad::OnInit(XUIMessageInit* pInitData,
|
|
BOOL& bHandled) {
|
|
m_iPad = *(int*)pInitData->pvInitData;
|
|
m_bReady = false;
|
|
MapChildControls();
|
|
|
|
m_iTexturePacksNotInstalled = 0;
|
|
m_iConfigA = NULL;
|
|
|
|
XuiControlSetText(m_LabelNoGames, app.GetString(IDS_NO_GAMES_FOUND));
|
|
XuiControlSetText(m_GamesList, app.GetString(IDS_JOIN_GAME));
|
|
XuiControlSetText(m_SavesList, app.GetString(IDS_START_GAME));
|
|
|
|
constexpr int LOCATOR_SIZE =
|
|
256; // Use this to allocate space to hold a ResourceLocator string
|
|
WCHAR szResourceLocator[LOCATOR_SIZE];
|
|
|
|
const ULONG_PTR c_ModuleHandle = (ULONG_PTR)GetModuleHandle(NULL);
|
|
swprintf(szResourceLocator, LOCATOR_SIZE, L"section://%X,%ls#%ls",
|
|
c_ModuleHandle, L"media", L"media/Graphics/TexturePackIcon.png");
|
|
|
|
m_DefaultMinecraftIconSize = 0;
|
|
HRESULT hr =
|
|
XuiResourceLoadAllNoLoc(szResourceLocator, &m_DefaultMinecraftIconData,
|
|
&m_DefaultMinecraftIconSize);
|
|
|
|
m_localPlayers = 1;
|
|
m_bKillSaveInfoEnumerate = false;
|
|
|
|
m_bShowingPartyGamesOnly = false;
|
|
|
|
m_bRetrievingSaveInfo = false;
|
|
m_bSaveTransferInProgress = false;
|
|
|
|
// check for a default custom cloak in the global storage
|
|
// 4J-PB - changed to a config file
|
|
// if(ProfileManager.IsSignedInLive( m_iPad ))
|
|
// {
|
|
// app.InstallDefaultCape();
|
|
// }
|
|
|
|
m_initData = new JoinMenuInitData();
|
|
m_bMultiplayerAllowed = ProfileManager.IsSignedInLive(m_iPad) &&
|
|
ProfileManager.AllowedToPlayMultiplayer(m_iPad);
|
|
|
|
XPARTY_USER_LIST partyList;
|
|
|
|
if ((XPartyGetUserList(&partyList) != XPARTY_E_NOT_IN_PARTY) &&
|
|
(partyList.dwUserCount > 1)) {
|
|
m_bInParty = true;
|
|
} else {
|
|
m_bInParty = false;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
|
|
XuiSetTimer(m_hObj, JOIN_LOAD_ONLINE_TIMER_ID, JOIN_LOAD_ONLINE_TIMER_TIME);
|
|
|
|
m_iSaveInfoC = 0;
|
|
|
|
void* pObj;
|
|
XuiObjectFromHandle(m_SavesList, &pObj);
|
|
m_pSavesList = (CXuiCtrl4JList*)pObj;
|
|
|
|
XuiObjectFromHandle(m_GamesList, &pObj);
|
|
m_pGamesList = (CXuiCtrl4JList*)pObj;
|
|
|
|
// 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) {
|
|
// not doing a mount, so enable input
|
|
m_bIgnoreInput = true;
|
|
} else {
|
|
// 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 = false;
|
|
|
|
m_iChangingSaveGameInfoIndex = 0;
|
|
|
|
m_generators = app.getLevelGenerators();
|
|
m_iDefaultButtonsC = 0;
|
|
m_iMashUpButtonsC = 0;
|
|
|
|
// check if we're in the trial version
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, -1, -1, -1, iLB);
|
|
|
|
AddDefaultButtons();
|
|
|
|
m_pSavesList->SetCurSelVisible(0);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
if (StorageManager.GetSaveDeviceSelected(m_iPad)) {
|
|
// saving is disabled, but we should still be able to load from
|
|
// a selected save device
|
|
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, -1,
|
|
-1, -1, iLB, IDS_TOOLTIPS_DELETESAVE);
|
|
|
|
GetSaveInfo();
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, -1,
|
|
-1, -1, iLB);
|
|
|
|
AddDefaultButtons();
|
|
m_SavesListTimer.SetShow(FALSE);
|
|
|
|
m_pSavesList->SetCurSelVisible(0);
|
|
}
|
|
} 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();
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, -1, -1,
|
|
-1, -1,
|
|
bCanRename ? IDS_TOOLTIPS_SAVEOPTIONS
|
|
: IDS_TOOLTIPS_DELETESAVE);
|
|
|
|
GetSaveInfo();
|
|
}
|
|
}
|
|
// XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, TRUE);
|
|
|
|
UpdateGamesList();
|
|
|
|
g_NetworkManager.SetSessionsUpdatedCallback(
|
|
&CScene_MultiGameJoinLoad::UpdateGamesListCallback, this);
|
|
|
|
// 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.
|
|
MinecraftServer::resetFlags();
|
|
|
|
// 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();
|
|
}
|
|
|
|
// 4J-PB - Load up any texture pack data we have locally in the XZP
|
|
for (int i = 0; i < TMS_COUNT; i++) {
|
|
if (app.TMSFileA[i].eTMSType == eTMSFileType_TexturePack) {
|
|
app.LoadLocalTMSFile(app.TMSFileA[i].wchFilename,
|
|
app.TMSFileA[i].eEXT);
|
|
app.AddMemoryTPDFile(app.TMSFileA[i].iConfig,
|
|
app.TMSFileA[i].pbData,
|
|
app.TMSFileA[i].uiSize);
|
|
}
|
|
}
|
|
|
|
// 4J-PB - there may be texture packs we don't have, so use the info from
|
|
// TMS for this
|
|
|
|
DLC_INFO* pDLCInfo = NULL;
|
|
|
|
// first pass - look to see if there are any that are not in the list
|
|
bool bTexturePackAlreadyListed;
|
|
bool bNeedToGetTPD = false;
|
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
|
int texturePacksCount = pMinecraft->skins->getTexturePackCount();
|
|
// CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
// HRESULT hr;
|
|
|
|
for (unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) {
|
|
bTexturePackAlreadyListed = false;
|
|
ULONGLONG ull = app.GetDLCInfoTexturesFullOffer(i);
|
|
pDLCInfo = app.GetDLCInfoForFullOfferID(ull);
|
|
for (unsigned int i = 0; i < texturePacksCount; ++i) {
|
|
TexturePack* tp = pMinecraft->skins->getTexturePackByIndex(i);
|
|
if (pDLCInfo->iConfig == tp->getDLCParentPackId()) {
|
|
bTexturePackAlreadyListed = true;
|
|
}
|
|
}
|
|
if (bTexturePackAlreadyListed == false) {
|
|
// some missing
|
|
bNeedToGetTPD = true;
|
|
|
|
m_iTexturePacksNotInstalled++;
|
|
}
|
|
}
|
|
|
|
if (bNeedToGetTPD == true) {
|
|
// add a TMS request for them
|
|
app.DebugPrintf("+++ Adding TMSPP request for texture pack data\n");
|
|
app.AddTMSPPFileTypeRequest(e_DLC_TexturePackData);
|
|
m_iConfigA = new int[m_iTexturePacksNotInstalled];
|
|
m_iTexturePacksNotInstalled = 0;
|
|
|
|
for (unsigned int i = 0; i < app.GetDLCInfoTexturesOffersCount(); ++i) {
|
|
bTexturePackAlreadyListed = false;
|
|
ULONGLONG ull = app.GetDLCInfoTexturesFullOffer(i);
|
|
pDLCInfo = app.GetDLCInfoForFullOfferID(ull);
|
|
for (unsigned int i = 0; i < texturePacksCount; ++i) {
|
|
TexturePack* tp = pMinecraft->skins->getTexturePackByIndex(i);
|
|
if (pDLCInfo->iConfig == tp->getDLCParentPackId()) {
|
|
bTexturePackAlreadyListed = true;
|
|
}
|
|
}
|
|
if (bTexturePackAlreadyListed == false) {
|
|
m_iConfigA[m_iTexturePacksNotInstalled++] = pDLCInfo->iConfig;
|
|
}
|
|
}
|
|
}
|
|
|
|
XuiSetTimer(m_hObj, CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,
|
|
CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::AddDefaultButtons() {
|
|
CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
|
|
// Add two for New Game and Tutorial
|
|
ZeroMemory(&ListInfo, sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
|
|
|
|
ListInfo.pwszText = app.GetString(IDS_CREATE_NEW_WORLD);
|
|
ListInfo.fEnabled = TRUE;
|
|
ListInfo.iData = -1;
|
|
m_pSavesList->AddData(ListInfo);
|
|
|
|
int iSavesListIndex = 0;
|
|
int iGeneratorIndex = 0;
|
|
m_iMashUpButtonsC = 0;
|
|
|
|
for (AUTO_VAR(it, m_generators->begin()); it != m_generators->end(); ++it) {
|
|
LevelGenerationOptions* levelGen = *it;
|
|
ListInfo.pwszText = levelGen->getWorldName();
|
|
ListInfo.fEnabled = TRUE;
|
|
ListInfo.iData =
|
|
iGeneratorIndex++; // used to index into the list of generators
|
|
|
|
// need to check if the user has disabled this pack in the save display
|
|
// list
|
|
unsigned int uiTexturePackID = levelGen->getRequiredTexturePackId();
|
|
|
|
if (uiTexturePackID != 0) {
|
|
unsigned int uiMashUpWorldsBitmask =
|
|
app.GetMashupPackWorlds(m_iPad);
|
|
|
|
if ((uiMashUpWorldsBitmask & (1 << (uiTexturePackID - 1024))) ==
|
|
0) {
|
|
// this world is hidden, so skip
|
|
continue;
|
|
}
|
|
}
|
|
m_pSavesList->AddData(ListInfo);
|
|
|
|
// retrieve the save icon from the texture pack, if there is one
|
|
if (uiTexturePackID != 0) {
|
|
// increment the count of the mash-up pack worlds in the save list
|
|
m_iMashUpButtonsC++;
|
|
TexturePack* tp =
|
|
Minecraft::GetInstance()->skins->getTexturePackById(
|
|
levelGen->getRequiredTexturePackId());
|
|
std::uint32_t imageBytes = 0;
|
|
std::uint8_t* imageData = tp->getPackIcon(imageBytes);
|
|
HXUIBRUSH hXuiBrush;
|
|
|
|
if (imageBytes > 0 && imageData) {
|
|
XuiCreateTextureBrushFromMemory(imageData, imageBytes,
|
|
&hXuiBrush);
|
|
// the index inside the list item for this will be i+1 because
|
|
// they start at m_vListData.size(), so the first etry
|
|
// (tutorial) is 1
|
|
m_pSavesList->UpdateGraphic(iSavesListIndex + 1, hXuiBrush);
|
|
}
|
|
}
|
|
|
|
++iSavesListIndex;
|
|
}
|
|
|
|
m_iDefaultButtonsC = iSavesListIndex + 1;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::GetSaveInfo() {
|
|
unsigned int uiSaveC = 0;
|
|
|
|
// This will return with the number retrieved in uiSaveC
|
|
|
|
if (app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) {
|
|
uiSaveC = 0;
|
|
File savesDir(L"GAME:\\Saves");
|
|
if (savesDir.exists()) {
|
|
m_saves = savesDir.listFiles();
|
|
uiSaveC = (unsigned int)m_saves->size();
|
|
}
|
|
// add the New Game and Tutorial after the saves list is retrieved, if
|
|
// there are any saves
|
|
|
|
// Add two for New Game and Tutorial
|
|
unsigned int listItems = uiSaveC;
|
|
|
|
CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
ZeroMemory(&ListInfo, sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
|
|
|
|
AddDefaultButtons();
|
|
|
|
for (unsigned int i = 0; i < listItems; i++) {
|
|
std::wstring wName = m_saves->at(i)->getName();
|
|
wchar_t* name = new wchar_t[wName.size() + 1];
|
|
for (unsigned int j = 0; j < wName.size(); ++j) {
|
|
name[j] = wName[j];
|
|
}
|
|
name[wName.size()] = 0;
|
|
ListInfo.pwszText = name;
|
|
ListInfo.fEnabled = TRUE;
|
|
ListInfo.iData = -1;
|
|
m_pSavesList->AddData(ListInfo);
|
|
}
|
|
m_pSavesList->SetCurSelVisible(0);
|
|
} else {
|
|
m_bRetrievingSaveInfo =
|
|
true; // we're blocking the exit from this scene until complete
|
|
|
|
// clear the saves list
|
|
m_pSavesList->RemoveAllData();
|
|
|
|
m_iSaveInfoC = 0;
|
|
#ifdef _XBOX
|
|
C4JStorage::ESGIStatus eSGIStatus = StorageManager.GetSavesInfo(
|
|
ProfileManager.GetPrimaryPad(),
|
|
&CScene_MultiGameJoinLoad::GetSavesInfoCallback, this,
|
|
"savegame.dat");
|
|
|
|
if (eSGIStatus == C4JStorage::ESGIStatus_NoSaves) {
|
|
uiSaveC = 0;
|
|
m_SavesListTimer.SetShow(FALSE);
|
|
m_SavesList.SetEnable(TRUE);
|
|
}
|
|
#else
|
|
|
|
// C4JStorage::ESaveGameState
|
|
// eStatus=StorageManager.GetSavesInfo(ProfileManager.GetPrimaryPad(),&CScene_MultiGameJoinLoad::GetSavesInfoCallback,this,"savegame.dat");
|
|
|
|
#endif
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnDestroy() {
|
|
g_NetworkManager.SetSessionsUpdatedCallback(NULL, NULL);
|
|
|
|
for (AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end();
|
|
++it) {
|
|
delete (*it);
|
|
}
|
|
|
|
if (m_bSaveTransferInProgress) {
|
|
CancelSaveUploadCallback(this);
|
|
}
|
|
|
|
// Reset the background downloading, in case we changed it by attempting to
|
|
// download a texture pack
|
|
XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
|
|
|
|
// clear out the texture pack data
|
|
for (int i = 0; i < TMS_COUNT; i++) {
|
|
if (app.TMSFileA[i].eTMSType == eTMSFileType_TexturePack) {
|
|
app.RemoveMemoryTPDFile(app.TMSFileA[i].iConfig);
|
|
}
|
|
}
|
|
app.FreeLocalTMSFiles(eTMSFileType_TexturePack);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::DeviceRemovedDialogReturned(
|
|
void* pParam, int iPad, C4JStorage::EMessageResult result) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
// results switched for this dialog
|
|
if (result == C4JStorage::EMessage_ResultDecline) {
|
|
StorageManager.SetSaveDisabled(true);
|
|
StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),
|
|
false);
|
|
// use the device select returned function to wipe the saves list and
|
|
// change the tooltip
|
|
CScene_MultiGameJoinLoad::DeviceSelectReturned(pClass, true);
|
|
} else // continue without saving
|
|
{
|
|
// Change device
|
|
StorageManager.SetSaveDevice(
|
|
&CScene_MultiGameJoinLoad::DeviceSelectReturned, pClass, true);
|
|
}
|
|
|
|
pClass->m_bIgnoreInput = false;
|
|
return 0;
|
|
}
|
|
//----------------------------------------------------------------------------------
|
|
// Handler for the button press message.
|
|
//----------------------------------------------------------------------------------
|
|
HRESULT CScene_MultiGameJoinLoad::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_GamesList) {
|
|
m_bIgnoreInput = true;
|
|
|
|
int nIndex = m_pGamesList->GetCurSel();
|
|
|
|
if (m_pGamesList->GetItemCount() > 0 &&
|
|
nIndex < currentSessions.size()) {
|
|
// CScene_MultiGameInfo::JoinMenuInitData *initData = new
|
|
// CScene_MultiGameInfo::JoinMenuInitData();
|
|
m_initData->iPad = m_iPad;
|
|
m_initData->selectedSession = currentSessions.at(nIndex);
|
|
|
|
// check that we have the texture pack available
|
|
// If it's not the default texture pack
|
|
if (m_initData->selectedSession->data.texturePackParentId != 0) {
|
|
int texturePacksCount =
|
|
Minecraft::GetInstance()->skins->getTexturePackCount();
|
|
bool bHasTexturePackInstalled = false;
|
|
|
|
for (int i = 0; i < texturePacksCount; i++) {
|
|
TexturePack* tp =
|
|
Minecraft::GetInstance()->skins->getTexturePackByIndex(
|
|
i);
|
|
if (tp->getDLCParentPackId() ==
|
|
m_initData->selectedSession->data.texturePackParentId) {
|
|
bHasTexturePackInstalled = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bHasTexturePackInstalled == false) {
|
|
// upsell the texture pack
|
|
// tell sentient about the upsell of the full version of the
|
|
// skin pack
|
|
ULONGLONG ullOfferID_Full;
|
|
app.GetDLCFullOfferIDForPackID(
|
|
m_initData->selectedSession->data.texturePackParentId,
|
|
&ullOfferID_Full);
|
|
|
|
TelemetryManager->RecordUpsellPresented(
|
|
pNotifyPressData->UserIndex, eSet_UpsellID_Texture_DLC,
|
|
ullOfferID_Full & 0xFFFFFFFF);
|
|
|
|
unsigned int uiIDA[3];
|
|
|
|
// Need to check if the texture pack has both Full and Trial
|
|
// versions - we may do some as free ones, so only Full
|
|
DLC_INFO* pDLCInfo =
|
|
app.GetDLCInfoForFullOfferID(ullOfferID_Full);
|
|
|
|
if (pDLCInfo->ullOfferID_Trial != 0LL) {
|
|
uiIDA[0] = IDS_TEXTUREPACK_FULLVERSION;
|
|
uiIDA[1] = IDS_TEXTURE_PACK_TRIALVERSION;
|
|
uiIDA[2] = IDS_CONFIRM_CANCEL;
|
|
// Give the player a warning about the texture pack
|
|
// missing
|
|
StorageManager.RequestMessageBox(
|
|
IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE,
|
|
IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 3,
|
|
ProfileManager.GetPrimaryPad(),
|
|
&CScene_MultiGameJoinLoad::
|
|
TexturePackDialogReturned,
|
|
this, app.GetStringTable());
|
|
} else {
|
|
uiIDA[0] = IDS_TEXTUREPACK_FULLVERSION;
|
|
uiIDA[1] = IDS_CONFIRM_CANCEL;
|
|
// Give the player a warning about the texture pack
|
|
// missing
|
|
StorageManager.RequestMessageBox(
|
|
IDS_DLC_TEXTUREPACK_NOT_PRESENT_TITLE,
|
|
IDS_DLC_TEXTUREPACK_NOT_PRESENT, uiIDA, 2,
|
|
ProfileManager.GetPrimaryPad(),
|
|
&CScene_MultiGameJoinLoad::
|
|
TexturePackDialogReturned,
|
|
this, app.GetStringTable());
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
}
|
|
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
|
|
// Reset the background downloading, in case we changed it by
|
|
// attempting to download a texture pack
|
|
XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
|
|
|
|
// kill the texture pack check timer
|
|
XuiKillTimer(m_hObj, CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
|
|
app.NavigateToScene(pNotifyPressData->UserIndex, eUIScene_JoinMenu,
|
|
m_initData);
|
|
}
|
|
} else if (hObjPressed == m_SavesList) {
|
|
m_bIgnoreInput = true;
|
|
|
|
CXuiControl pItem;
|
|
int iIndex;
|
|
// get the selected item
|
|
iIndex = m_SavesList.GetCurSel(&pItem);
|
|
|
|
CXuiCtrl4JList::LIST_ITEM_INFO info = m_pSavesList->GetData(iIndex);
|
|
|
|
if (iIndex == JOIN_LOAD_CREATE_BUTTON_INDEX) {
|
|
app.SetTutorialMode(false);
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
|
|
app.SetCorruptSaveDeleted(false);
|
|
|
|
CreateWorldMenuInitData* params = new CreateWorldMenuInitData();
|
|
params->iPad = m_iPad;
|
|
app.NavigateToScene(pNotifyPressData->UserIndex,
|
|
eUIScene_CreateWorldMenu, (void*)params);
|
|
} else if (info.iData >= 0) {
|
|
LevelGenerationOptions* levelGen = m_generators->at(info.iData);
|
|
app.SetTutorialMode(levelGen->isTutorial());
|
|
// Reset the autosave time
|
|
app.SetAutosaveTimerTime();
|
|
|
|
if (levelGen->isTutorial()) {
|
|
LoadLevelGen(levelGen);
|
|
} else {
|
|
LoadMenuInitData* params = new LoadMenuInitData();
|
|
params->iPad = m_iPad;
|
|
// 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
|
|
params->iSaveGameInfoIndex = -1;
|
|
// params->pbSaveRenamed=&m_bSaveRenamed;
|
|
params->levelGen = levelGen;
|
|
|
|
// navigate to the settings scene
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),
|
|
eUIScene_LoadMenu, params);
|
|
}
|
|
} else {
|
|
// check if this is a damaged save
|
|
if (m_pSavesList->GetData(iIndex).bIsDamaged) {
|
|
// give the option to delete the save
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE,
|
|
IDS_CORRUPT_OR_DAMAGED_SAVE_TEXT, uiIDA, 2,
|
|
pNotifyPressData->UserIndex,
|
|
&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned, this,
|
|
app.GetStringTable());
|
|
} else {
|
|
app.SetTutorialMode(false);
|
|
if (app.DebugSettingsOn() &&
|
|
app.GetLoadSavesFromFolderEnabled()) {
|
|
LoadSaveFromDisk(m_saves->at(iIndex - m_iDefaultButtonsC));
|
|
} else {
|
|
LoadMenuInitData* params = new LoadMenuInitData();
|
|
params->iPad = m_iPad;
|
|
// 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
|
|
params->iSaveGameInfoIndex =
|
|
m_pSavesList->GetData(iIndex).iIndex -
|
|
m_iDefaultButtonsC;
|
|
// params->pbSaveRenamed=&m_bSaveRenamed;
|
|
params->levelGen = NULL;
|
|
|
|
// kill the texture pack timer
|
|
XuiKillTimer(m_hObj,
|
|
CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
|
|
// navigate to the settings scene
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),
|
|
eUIScene_LoadMenu, params);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::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:
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
|
|
app.NavigateBack(XUSER_INDEX_ANY);
|
|
rfHandled = TRUE;
|
|
break;
|
|
case VK_PAD_X:
|
|
|
|
// Change device
|
|
// Fix for #12531 - TCR 001: BAS Game Stability: When a player
|
|
// selects to change a storage device, and repeatedly backs out of
|
|
// the SD screen, disconnects from LIVE, and then selects a SD, the
|
|
// title crashes.
|
|
m_bIgnoreInput = true;
|
|
StorageManager.SetSaveDevice(
|
|
&CScene_MultiGameJoinLoad::DeviceSelectReturned, this, true);
|
|
CXuiSceneBase::PlayUISFX(eSFX_Press);
|
|
break;
|
|
case VK_PAD_Y:
|
|
if (m_pGamesList->TreeHasFocus() &&
|
|
m_pGamesList->GetItemCount() > 0) {
|
|
int nIndex = m_pGamesList->GetCurSel();
|
|
FriendSessionInfo* pSelectedSession =
|
|
currentSessions.at(nIndex);
|
|
|
|
PlayerUID xuid = pSelectedSession->data.hostPlayerUID;
|
|
if (xuid != INVALID_XUID)
|
|
hr = XShowGamerCardUI(ProfileManager.GetLockedProfile(),
|
|
xuid);
|
|
CXuiSceneBase::PlayUISFX(eSFX_Press);
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
// save transfer - make sure they want to overwrite a save that
|
|
// is up there
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
// 4J-PB - required for a delete of the save if it's found
|
|
// to be a corrupted save
|
|
int nIndex = m_pSavesList->GetCurSel();
|
|
m_iChangingSaveGameInfoIndex =
|
|
m_pSavesList->GetData(nIndex).iIndex;
|
|
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_UPLOAD_SAVE;
|
|
uiIDA[1] = IDS_CONFIRM_CANCEL;
|
|
|
|
ui.RequestMessageBox(
|
|
IDS_SAVE_TRANSFER_TITLE, IDS_SAVE_TRANSFER_TEXT, uiIDA,
|
|
2, pInputData->UserIndex,
|
|
&CScene_MultiGameJoinLoad::SaveTransferDialogReturned,
|
|
this, app.GetStringTable());
|
|
}
|
|
}
|
|
break;
|
|
case VK_PAD_RSHOULDER:
|
|
if (DoesSavesListHaveFocus()) {
|
|
m_bIgnoreInput = true;
|
|
|
|
int iIndex = m_SavesList.GetCurSel();
|
|
m_iChangingSaveGameInfoIndex =
|
|
m_pSavesList->GetData(iIndex).iIndex;
|
|
|
|
// Could be delete save or Save Options
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
// delete the save game
|
|
// Have to ask the player if they are sure they want to
|
|
// delete this game
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2,
|
|
pInputData->UserIndex,
|
|
&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,
|
|
this, app.GetStringTable());
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
unsigned int uiIDA[3];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_TITLE_RENAMESAVE;
|
|
uiIDA[2] = IDS_TOOLTIPS_DELETESAVE;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_TOOLTIPS_SAVEOPTIONS, IDS_TEXT_SAVEOPTIONS,
|
|
uiIDA, 3, pInputData->UserIndex,
|
|
&CScene_MultiGameJoinLoad::
|
|
SaveOptionsDialogReturned,
|
|
this, app.GetStringTable());
|
|
} else {
|
|
// delete the save game
|
|
// Have to ask the player if they are sure they want to
|
|
// delete this game
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE,
|
|
uiIDA, 2, pInputData->UserIndex,
|
|
&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned,
|
|
this, app.GetStringTable());
|
|
}
|
|
}
|
|
CXuiSceneBase::PlayUISFX(eSFX_Press);
|
|
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// hiding a mash-up world
|
|
// get the mash-up pack id
|
|
CXuiControl pItem;
|
|
int iIndex;
|
|
iIndex = m_SavesList.GetCurSel(&pItem);
|
|
|
|
CXuiCtrl4JList::LIST_ITEM_INFO info =
|
|
m_pSavesList->GetData(iIndex);
|
|
if ((iIndex != JOIN_LOAD_CREATE_BUTTON_INDEX) &&
|
|
(info.iData >= 0)) {
|
|
LevelGenerationOptions* levelGen =
|
|
m_generators->at(info.iData);
|
|
|
|
if (!levelGen->isTutorial()) {
|
|
if (levelGen->requiresTexturePack()) {
|
|
unsigned int uiPackID =
|
|
levelGen->getRequiredTexturePackId();
|
|
|
|
m_bIgnoreInput = true;
|
|
app.HideMashupPackWorld(m_iPad, uiPackID);
|
|
|
|
// update the saves list
|
|
m_pSavesList->RemoveAllData();
|
|
m_iSaveInfoC = 0;
|
|
GetSaveInfo();
|
|
m_bIgnoreInput = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
CXuiSceneBase::PlayUISFX(eSFX_Press);
|
|
}
|
|
break;
|
|
case VK_PAD_LSHOULDER:
|
|
if (m_bInParty) {
|
|
m_bShowingPartyGamesOnly = !m_bShowingPartyGamesOnly;
|
|
UpdateGamesList();
|
|
CXuiSceneBase::PlayUISFX(eSFX_Press);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnNavReturn(HXUIOBJ hSceneFrom,
|
|
BOOL& rfHandled) {
|
|
CXuiSceneBase::ShowLogo(DEFAULT_XUI_MENU_USER, TRUE);
|
|
// start the texture pack timer again
|
|
XuiSetTimer(m_hObj, CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID,
|
|
CHECKFORAVAILABLETEXTUREPACKS_TIMER_TIME);
|
|
|
|
m_bMultiplayerAllowed = ProfileManager.IsSignedInLive(m_iPad) &&
|
|
ProfileManager.AllowedToPlayMultiplayer(m_iPad);
|
|
|
|
// re-enable button presses
|
|
m_bIgnoreInput = false;
|
|
|
|
if (m_bMultiplayerAllowed) {
|
|
HXUICLASS hClassFullscreenProgress =
|
|
XuiFindClass(L"CScene_FullscreenProgress");
|
|
HXUICLASS hClassConnectingProgress =
|
|
XuiFindClass(L"CScene_ConnectingProgress");
|
|
|
|
// If we are navigating back from a full screen progress scene, then
|
|
// that means a connection attempt failed
|
|
if (XuiIsInstanceOf(hSceneFrom, hClassFullscreenProgress) ||
|
|
XuiIsInstanceOf(hSceneFrom, hClassConnectingProgress)) {
|
|
UpdateGamesList();
|
|
}
|
|
} else {
|
|
m_pGamesList->RemoveAllData();
|
|
// m_GamesList.DeleteItems(0, m_GamesList.GetItemCount() );
|
|
m_pGamesList->SetEnable(FALSE);
|
|
// XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, TRUE);
|
|
m_NetGamesListTimer.SetShow(TRUE);
|
|
m_LabelNoGames.SetShow(FALSE);
|
|
m_SavesList.InitFocus(m_iPad);
|
|
}
|
|
|
|
// are we back here because of a delete of a corrupt save?
|
|
|
|
if (app.GetCorruptSaveDeleted()) {
|
|
// need to re-get the saves list and update the display
|
|
// clear the saves list
|
|
m_pSavesList->RemoveAllData();
|
|
m_iSaveInfoC = 0;
|
|
GetSaveInfo();
|
|
app.SetCorruptSaveDeleted(false);
|
|
}
|
|
|
|
int iY = -1;
|
|
int iRB = -1;
|
|
if (DoesGamesListHaveFocus()) {
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
// 4J-PB - we need to check that there is enough space left to
|
|
// create a copy of the save (for a rename)
|
|
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) {
|
|
if (m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, -1, -1, -1, iLB);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
// clear out the saves list, since the disable save may have happened in
|
|
// the load screen because of a device removal
|
|
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnNotifySelChanged(
|
|
HXUIOBJ hObjSource, XUINotifySelChanged* pNotifySelChangedData,
|
|
BOOL& bHandled) {
|
|
if (m_bReady) {
|
|
CXuiSceneBase::PlayUISFX(eSFX_Focus);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::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);
|
|
|
|
KillTimer(JOIN_LOAD_ONLINE_TIMER_ID);
|
|
} else if (pTransition->dwTransType == XUI_TRANSITION_TO ||
|
|
pTransition->dwTransType == XUI_TRANSITION_BACKTO) {
|
|
SetTimer(JOIN_LOAD_ONLINE_TIMER_ID, JOIN_LOAD_ONLINE_TIMER_TIME);
|
|
// 4J-PB - Need to check for installed DLC, which might have happened
|
|
// while you were on the info scene
|
|
if (pTransition->dwTransType == XUI_TRANSITION_BACKTO) {
|
|
// Can't call this here because if you back out of the load info
|
|
// screen and then go back in and load a game, it will attempt to
|
|
// use the dlc as it's running a mount of the dlc
|
|
|
|
// 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) == false) {
|
|
// not doing a mount, so re-enable input
|
|
m_bIgnoreInput = false;
|
|
} else {
|
|
m_bIgnoreInput = true;
|
|
m_pSavesList->RemoveAllData();
|
|
m_SavesListTimer.SetShow(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnFontRendererChange() {
|
|
// update the tooltips
|
|
// if the saves list has focus, then we should show the Delete Save tooltip
|
|
// if the games list has focus, then we should the the View Gamercard
|
|
// tooltip
|
|
int iRB = -1;
|
|
int iY = -1;
|
|
if (DoesGamesListHaveFocus()) {
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) {
|
|
if (m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, iY, -1, -1, iLB, -1, -1, true);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY, -1, -1,
|
|
iLB, iRB, -1, true);
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1, -1,
|
|
iLB, iRB, -1, true);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnNotifySetFocus(
|
|
HXUIOBJ hObjSource, XUINotifyFocus* pNotifyFocusData, BOOL& bHandled) {
|
|
// update the tooltips
|
|
// if the saves list has focus, then we should show the Delete Save tooltip
|
|
// if the games list has focus, then we should the the View Gamercard
|
|
// tooltip
|
|
int iRB = -1;
|
|
int iY = -1;
|
|
if (DoesGamesListHaveFocus()) {
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) {
|
|
if (m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, iY, -1, -1, iLB, -1);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnNotifyKillFocus(
|
|
HXUIOBJ hObjSource, XUINotifyFocus* pNotifyFocusData, BOOL& bHandled) {
|
|
return S_OK;
|
|
}
|
|
|
|
bool CScene_MultiGameJoinLoad::DoesSavesListHaveFocus() {
|
|
HXUIOBJ hParentObj, hObj = TreeGetFocus();
|
|
|
|
if (hObj != NULL) {
|
|
// get the parent and see if it's the saves list
|
|
XuiElementGetParent(hObj, &hParentObj);
|
|
if (hParentObj == m_SavesList.m_hObj) {
|
|
// check it's not the first or second element (new world or
|
|
// tutorial)
|
|
if (m_SavesList.GetCurSel() > (m_iDefaultButtonsC - 1)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CScene_MultiGameJoinLoad::DoesMashUpWorldHaveFocus() {
|
|
HXUIOBJ hParentObj, hObj = TreeGetFocus();
|
|
|
|
if (hObj != NULL) {
|
|
// get the parent and see if it's the saves list
|
|
XuiElementGetParent(hObj, &hParentObj);
|
|
if (hParentObj == m_SavesList.m_hObj) {
|
|
// check it's not the first or second element (new world or
|
|
// tutorial)
|
|
if (m_SavesList.GetCurSel() > (m_iDefaultButtonsC - 1)) {
|
|
return false;
|
|
}
|
|
|
|
if (m_SavesList.GetCurSel() >
|
|
(m_iDefaultButtonsC - 1 - m_iMashUpButtonsC)) {
|
|
return true;
|
|
} else
|
|
return false;
|
|
} else
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CScene_MultiGameJoinLoad::DoesGamesListHaveFocus() {
|
|
HXUIOBJ hParentObj, hObj = TreeGetFocus();
|
|
|
|
if (hObj != NULL) {
|
|
// get the parent and see if it's the saves list
|
|
XuiElementGetParent(hObj, &hParentObj);
|
|
if (hParentObj == m_pGamesList->m_hObj) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::UpdateGamesListCallback(LPVOID lpParam) {
|
|
if (lpParam != NULL) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)lpParam;
|
|
// check this there's no save transfer in progress
|
|
if (!pClass->m_bSaveTransferInProgress) {
|
|
pClass->UpdateGamesList();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::UpdateGamesList() {
|
|
if (m_bIgnoreInput) return;
|
|
|
|
// if we're retrieving save info, don't show the list yet as we will be
|
|
// ignoring press events
|
|
if (m_bRetrievingSaveInfo) {
|
|
return;
|
|
}
|
|
|
|
int nIndex = -1;
|
|
FriendSessionInfo* pSelectedSession = NULL;
|
|
if (m_pGamesList->TreeHasFocus() && m_pGamesList->GetItemCount() > 0) {
|
|
nIndex = m_pGamesList->GetCurSel();
|
|
pSelectedSession = currentSessions.at(nIndex);
|
|
}
|
|
|
|
SessionID selectedSessionId;
|
|
if (pSelectedSession != NULL)
|
|
selectedSessionId = pSelectedSession->sessionId;
|
|
pSelectedSession = NULL;
|
|
|
|
for (AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end();
|
|
++it) {
|
|
delete (*it);
|
|
}
|
|
currentSessions.clear();
|
|
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
|
|
// if the saves list has focus, then we should show the Delete Save tooltip
|
|
// if the games list has focus, then we should show the View Gamercard
|
|
// tooltip
|
|
int iRB = -1;
|
|
int iY = -1;
|
|
|
|
if (DoesGamesListHaveFocus()) {
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) {
|
|
if (m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, iY, -1, -1, iLB, -1);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1, -1,
|
|
iLB, iRB);
|
|
}
|
|
|
|
currentSessions = *g_NetworkManager.GetSessionList(
|
|
m_iPad, m_localPlayers, m_bShowingPartyGamesOnly);
|
|
|
|
// Update the xui list displayed
|
|
unsigned int xuiListSize = m_pGamesList->GetItemCount();
|
|
unsigned int filteredListSize = (unsigned int)currentSessions.size();
|
|
|
|
bool gamesListHasFocus = m_pGamesList->TreeHasFocus() != FALSE;
|
|
|
|
if (filteredListSize > 0) {
|
|
if (!m_pGamesList->IsEnabled()) {
|
|
m_pGamesList->SetEnable(TRUE);
|
|
// XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj, FALSE);
|
|
m_pGamesList->SetCurSel(0);
|
|
}
|
|
m_LabelNoGames.SetShow(FALSE);
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
} else {
|
|
m_pGamesList->SetEnable(FALSE);
|
|
// XuiElementSetDisableFocusRecursion(m_pGamesList->m_hObj, TRUE);
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
m_LabelNoGames.SetShow(TRUE);
|
|
|
|
if (gamesListHasFocus) m_pGamesList->InitFocus(m_iPad);
|
|
}
|
|
|
|
// clear out the games list and re-fill
|
|
m_pGamesList->RemoveAllData();
|
|
|
|
if (filteredListSize > 0) {
|
|
// Reset the focus to the selected session if it still exists
|
|
unsigned int sessionIndex = 0;
|
|
m_pGamesList->SetCurSel(0);
|
|
|
|
for (AUTO_VAR(it, currentSessions.begin()); it < currentSessions.end();
|
|
++it) {
|
|
FriendSessionInfo* sessionInfo = *it;
|
|
HXUIBRUSH hXuiBrush;
|
|
CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
|
|
ZeroMemory(&ListInfo, sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
|
|
|
|
ListInfo.pwszText = sessionInfo->displayLabel;
|
|
ListInfo.fEnabled = TRUE;
|
|
ListInfo.iData = sessionIndex;
|
|
m_pGamesList->AddData(ListInfo);
|
|
// display an icon too
|
|
|
|
// Is this a default game or a texture pack game?
|
|
if (sessionInfo->data.texturePackParentId != 0) {
|
|
// Do we have the texture pack
|
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
|
TexturePack* tp = pMinecraft->skins->getTexturePackById(
|
|
sessionInfo->data.texturePackParentId);
|
|
HRESULT hr;
|
|
|
|
std::uint32_t imageBytes = 0;
|
|
std::uint8_t* imageData = NULL;
|
|
|
|
if (tp == NULL) {
|
|
unsigned int dwBytes = 0;
|
|
std::uint8_t* pbData = NULL;
|
|
app.GetTPD(sessionInfo->data.texturePackParentId, &pbData,
|
|
&dwBytes);
|
|
|
|
// is it in the tpd data ?
|
|
unsigned int tpdImageBytes = 0;
|
|
app.GetFileFromTPD(eTPDFileType_Icon, pbData, dwBytes,
|
|
&imageData, &tpdImageBytes);
|
|
imageBytes = static_cast<std::uint32_t>(tpdImageBytes);
|
|
if (imageBytes > 0 && imageData) {
|
|
hr = XuiCreateTextureBrushFromMemory(
|
|
imageData, imageBytes, &hXuiBrush);
|
|
m_pGamesList->UpdateGraphic(sessionIndex, hXuiBrush);
|
|
}
|
|
} else {
|
|
imageData = tp->getPackIcon(imageBytes);
|
|
if (imageBytes > 0 && imageData) {
|
|
hr = XuiCreateTextureBrushFromMemory(
|
|
imageData, imageBytes, &hXuiBrush);
|
|
m_pGamesList->UpdateGraphic(sessionIndex, hXuiBrush);
|
|
}
|
|
}
|
|
} else {
|
|
// default texture pack
|
|
XuiCreateTextureBrushFromMemory(m_DefaultMinecraftIconData,
|
|
m_DefaultMinecraftIconSize,
|
|
&hXuiBrush);
|
|
m_pGamesList->UpdateGraphic(sessionIndex, hXuiBrush);
|
|
}
|
|
|
|
if (memcmp(&selectedSessionId, &sessionInfo->sessionId,
|
|
sizeof(SessionID)) == 0) {
|
|
m_pGamesList->SetCurSel(sessionIndex);
|
|
break;
|
|
}
|
|
++sessionIndex;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::UpdateGamesList(DWORD dwNumResults,
|
|
IQNetGameSearch* pGameSearch) {
|
|
// We don't use the QNet callback, but could resurrect this if we ever do
|
|
// normal matchmaking, but updated to work as the function above
|
|
#if 0
|
|
const XSESSION_SEARCHRESULT *pSearchResult;
|
|
const XNQOSINFO * pxnqi;
|
|
|
|
if(m_searches>0)
|
|
--m_searches;
|
|
|
|
if(m_searches==0)
|
|
{
|
|
m_NetGamesListTimer.SetShow( FALSE );
|
|
|
|
// if the saves list has focus, then we should show the Delete Save tooltip
|
|
// if the games list has focus, then we should show the View Gamercard tooltip
|
|
int iRB=-1;
|
|
int iY = -1;
|
|
|
|
if( DoesGamesListHaveFocus() )
|
|
{
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
}
|
|
else if(DoesSavesListHaveFocus())
|
|
{
|
|
iRB=IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if(m_bInParty)
|
|
{
|
|
if( m_bShowingPartyGamesOnly ) iLB = IDS_TOOLTIPS_ALL_GAMES
|
|
else iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
if(ProfileManager.IsFullVersion()==false )
|
|
{
|
|
ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, -1, iY,-1,-1,iLB,iRB);
|
|
}
|
|
else if(StorageManager.GetSaveDisabled())
|
|
{
|
|
ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK,IDS_TOOLTIPS_SELECTDEVICE,iY,-1,-1,iLB,iRB);
|
|
}
|
|
else
|
|
{
|
|
ui.SetTooltips( DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,-1,-1,iLB,iRB);
|
|
}
|
|
}
|
|
|
|
if( dwNumResults == 0 )
|
|
{
|
|
if(m_searches==0 && m_GamesList.GetItemCount() == 0)
|
|
{
|
|
m_LabelNoGames.SetShow( TRUE );
|
|
}
|
|
return;
|
|
}
|
|
|
|
unsigned int startOffset = m_GamesList.GetItemCount();
|
|
//m_GamesList.InsertItems(startOffset,dwNumResults);
|
|
//m_GamesList.SetEnable(TRUE);
|
|
//XuiElementSetDisableFocusRecursion( m_GamesList.m_hObj, FALSE);
|
|
|
|
// Loop through all the results.
|
|
for( DWORD dwResult = 0; dwResult < pGameSearch->GetNumResults(); dwResult++ )
|
|
{
|
|
|
|
pSearchResult = pGameSearch->GetSearchResultAtIndex( dwResult );
|
|
|
|
// No room for us, so ignore it
|
|
if(pSearchResult->dwOpenPublicSlots < m_localPlayers)
|
|
continue;
|
|
|
|
FriendSessionInfo *sessionInfo = NULL;
|
|
bool foundSession = false;
|
|
for(AUTO_VAR(it, friendsSessions.begin()); it < friendsSessions.end(); ++it)
|
|
{
|
|
sessionInfo = *it;
|
|
if(memcmp( &pSearchResult->info.sessionID, &sessionInfo->sessionId, sizeof(SessionID) ) == 0)
|
|
{
|
|
sessionInfo->searchResult = *pSearchResult;
|
|
sessionInfo->displayLabel = new wchar_t[100];
|
|
foundSession = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// We received a search result for a session no longer in our list of friends sessions
|
|
if(!foundSession)
|
|
continue;
|
|
|
|
// Print some info about this result.
|
|
//printf( "Search result %u:\n", dwResult );
|
|
//printf( " public slots open = %u, filled = %u\n", pSearchResult->dwOpenPublicSlots, pSearchResult->dwFilledPublicSlots );
|
|
//printf( " private slots open = %u, filled = %u\n", pSearchResult->dwOpenPrivateSlots, pSearchResult->dwFilledPrivateSlots );
|
|
|
|
// See if this result was contacted successfully via QoS probes.
|
|
pxnqi = pGameSearch->GetQosInfoAtIndex( dwResult );
|
|
if( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_CONTACTED )
|
|
{
|
|
// Print the round trip time and the rough estimation of
|
|
// bandwidth.
|
|
app.DebugPrintf( " RTT min = %u, med = %u\n", pxnqi->wRttMinInMsecs, pxnqi->wRttMedInMsecs );
|
|
app.DebugPrintf( " bps up = %u, down = %u\n", pxnqi->dwUpBitsPerSec, pxnqi->dwDnBitsPerSec );
|
|
|
|
if(pxnqi->cbData > 0)
|
|
{
|
|
sessionInfo->data = *(GameSessionData *)pxnqi->pbData;
|
|
|
|
std::wstring gamerName = convStringToWstring(sessionInfo->data.hostName);
|
|
swprintf(sessionInfo->displayLabel,L"%ls's Game", gamerName.c_str() );
|
|
}
|
|
else
|
|
{
|
|
swprintf(sessionInfo->displayLabel,L"Unknown host Game");
|
|
}
|
|
|
|
// If this host wasn't disabled use this one.
|
|
if( !( pxnqi->bFlags & XNET_XNQOSINFO_TARGET_DISABLED ) && sessionInfo->data.netVersion == MINECRAFT_NET_VERSION )
|
|
{
|
|
//printf("This game is valid\n");
|
|
filteredResults.push_back(sessionInfo);
|
|
m_GamesList.InsertItems(startOffset,1);
|
|
m_GamesList.SetText(startOffset,sessionInfo->displayLabel);
|
|
startOffset++;
|
|
}
|
|
#ifndef _CONTENT_PACKAGE
|
|
if( sessionInfo->data.netVersion != MINECRAFT_NET_VERSION )
|
|
{
|
|
wprintf(L"%ls version of %d does not match our version of %d\n", sessionInfo->displayLabel, sessionInfo->data.netVersion, MINECRAFT_NET_VERSION);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if( m_GamesList.GetItemCount() == 0)
|
|
{
|
|
m_LabelNoGames.SetShow( TRUE );
|
|
}
|
|
else
|
|
{
|
|
m_GamesList.SetEnable(TRUE);
|
|
XuiElementSetDisableFocusRecursion( m_GamesList.m_hObj, FALSE);
|
|
if( DoesGamesListHaveFocus() )
|
|
{
|
|
m_GamesList.SetCurSel(0);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*void CScene_MultiGameJoinLoad::UpdateGamesListLabels()
|
|
{
|
|
for( unsigned int i = 0; i < currentSessions.size(); ++i )
|
|
{
|
|
FriendSessionInfo *sessionInfo = currentSessions.at(i);
|
|
m_GamesList.SetText(i,sessionInfo->displayLabel);
|
|
HXUIBRUSH hBrush;
|
|
CXuiCtrl4JList::LIST_ITEM_INFO info = m_pGamesList->GetData(i);
|
|
|
|
// display an icon too
|
|
XuiCreateTextureBrushFromMemory(m_DefaultMinecraftIconData,m_DefaultMinecraftIconSize,&hBrush);
|
|
m_pGamesList->UpdateGraphic(i,hBrush);
|
|
}
|
|
#if 0
|
|
XUIRect xuiRect;
|
|
HXUIOBJ item = XuiListGetItemControl(m_GamesList,0);
|
|
|
|
HXUIOBJ hObj=NULL;
|
|
HXUIOBJ hTextPres=NULL;
|
|
HRESULT hr=XuiControlGetVisual(item,&hObj);
|
|
hr=XuiElementGetChildById(hObj,L"text_Label",&hTextPres);
|
|
|
|
unsigned char displayLabelViewableStartIndex = 0;
|
|
for( unsigned int i = 0; i < currentSessions.size(); ++i )
|
|
{
|
|
FriendSessionInfo *sessionInfo = currentSessions.at(i);
|
|
|
|
if(hTextPres != NULL )
|
|
{
|
|
hr=XuiTextPresenterMeasureText(hTextPres,
|
|
sessionInfo->displayLabel, &xuiRect);
|
|
|
|
float fWidth, fHeight;
|
|
XuiElementGetBounds(hTextPres,&fWidth,&fHeight);
|
|
int characters = (fWidth/xuiRect.right) *
|
|
sessionInfo->displayLabelLength;
|
|
|
|
if( characters < sessionInfo->displayLabelLength )
|
|
{
|
|
static wchar_t temp[100];
|
|
ZeroMemory(temp, (100)*sizeof(wchar_t));
|
|
wcsncpy_s( temp,
|
|
sessionInfo->displayLabel+sessionInfo->displayLabelViewableStartIndex,
|
|
characters ); m_GamesList.SetText(i,temp);
|
|
sessionInfo->displayLabelViewableStartIndex++;
|
|
if( sessionInfo->displayLabelViewableStartIndex
|
|
>= sessionInfo->displayLabelLength ) sessionInfo->displayLabelViewableStartIndex
|
|
= 0;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}*/
|
|
|
|
void CScene_MultiGameJoinLoad::SearchForGameCallback(
|
|
void* param, DWORD dwNumResults, IQNetGameSearch* pGameSearch) {
|
|
#if 0
|
|
HXUIOBJ hObj = (HXUIOBJ)param;
|
|
|
|
void *pObj;
|
|
XuiObjectFromHandle( hObj, &pObj);
|
|
CScene_MultiGameJoinLoad *MultiGameJoinLoad = (CScene_MultiGameJoinLoad *)pObj;
|
|
|
|
MultiGameJoinLoad->UpdateGamesList(dwNumResults, pGameSearch);
|
|
#endif
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::DeviceSelectReturned(void* pParam,
|
|
bool bContinue) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
// HRESULT hr;
|
|
|
|
if (bContinue == true) {
|
|
// if the saves list has focus, then we should show the Delete Save
|
|
// tooltip if the games list has focus, then we should show the View
|
|
// Gamercard tooltip
|
|
int iRB = -1;
|
|
int iY = -1;
|
|
if (pClass->DoesGamesListHaveFocus()) {
|
|
iY = IDS_TOOLTIPS_VIEW_GAMERCARD;
|
|
} else if (pClass->DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(pClass->m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (pClass->DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (pClass->m_bInParty) {
|
|
if (pClass->m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
|
|
// BOOL bOnlineGame=pClass->m_CheckboxOnline.IsChecked();
|
|
|
|
// refresh the saves list (if there is a device selected)
|
|
|
|
// clear out the list first
|
|
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
if (StorageManager.GetSaveDeviceSelected(pClass->m_iPad)) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY,
|
|
-1, -1, iLB, iRB);
|
|
// saving is disabled, but we should still be able to load from
|
|
// a selected save device
|
|
pClass->GetSaveInfo();
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY,
|
|
-1, -1, iLB, iRB);
|
|
// clear the saves list
|
|
pClass->m_pSavesList->RemoveAllData();
|
|
|
|
pClass->m_iSaveInfoC = 0;
|
|
// pClass->m_iThumbnailsLoadedC=0;
|
|
|
|
pClass->AddDefaultButtons();
|
|
|
|
pClass->m_SavesListTimer.SetShow(FALSE);
|
|
|
|
pClass->m_pSavesList->SetCurSelVisible(0);
|
|
}
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1,
|
|
-1, iLB, iRB);
|
|
pClass->GetSaveInfo();
|
|
}
|
|
}
|
|
|
|
// enable input again
|
|
pClass->m_bIgnoreInput = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnTimer(XUIMessageTimer* pTimer,
|
|
BOOL& bHandled) {
|
|
// 4J-PB - TODO - Don't think we can do this - if a 2nd player signs in here
|
|
// with an offline profile, the signed in LIVE player gets re-logged in, and
|
|
// bMultiplayerAllowed is false briefly
|
|
switch (pTimer->nId) {
|
|
case JOIN_LOAD_ONLINE_TIMER_ID: {
|
|
XPARTY_USER_LIST partyList;
|
|
|
|
if ((XPartyGetUserList(&partyList) != XPARTY_E_NOT_IN_PARTY) &&
|
|
(partyList.dwUserCount > 1)) {
|
|
m_bInParty = true;
|
|
} else {
|
|
m_bInParty = false;
|
|
}
|
|
|
|
bool bMultiplayerAllowed =
|
|
ProfileManager.IsSignedInLive(m_iPad) &&
|
|
ProfileManager.AllowedToPlayMultiplayer(m_iPad);
|
|
if (bMultiplayerAllowed != m_bMultiplayerAllowed) {
|
|
if (bMultiplayerAllowed) {
|
|
// m_CheckboxOnline.SetEnable(TRUE);
|
|
// m_CheckboxPrivate.SetEnable(TRUE);
|
|
} else {
|
|
m_bInParty = false;
|
|
m_pGamesList->RemoveAllData();
|
|
// m_GamesList.DeleteItems(0, m_GamesList.GetItemCount() );
|
|
m_pGamesList->SetEnable(FALSE);
|
|
// XuiElementSetDisableFocusRecursion( m_pGamesList->m_hObj,
|
|
// TRUE);
|
|
m_NetGamesListTimer.SetShow(TRUE);
|
|
m_LabelNoGames.SetShow(FALSE);
|
|
}
|
|
|
|
int iLB = -1;
|
|
if (m_bInParty) {
|
|
if (m_bShowingPartyGamesOnly)
|
|
iLB = IDS_TOOLTIPS_ALL_GAMES;
|
|
else
|
|
iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
}
|
|
int iRB = -1;
|
|
int iY = -1;
|
|
|
|
if (DoesGamesListHaveFocus()) {
|
|
} else if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
|
|
if (StorageManager.GetSaveDisabled()) {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
} else {
|
|
if (StorageManager.EnoughSpaceForAMinSaveGame()) {
|
|
iRB = IDS_TOOLTIPS_SAVEOPTIONS;
|
|
} else {
|
|
iRB = IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
} else if (DoesMashUpWorldHaveFocus()) {
|
|
// If it's a mash-up pack world, give the Hide option
|
|
iRB = IDS_TOOLTIPS_HIDE;
|
|
}
|
|
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, -1, -1, -1, iLB);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE,
|
|
-1, -1, -1, iLB, iRB);
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE,
|
|
iY, -1, -1, iLB, iRB);
|
|
}
|
|
m_bMultiplayerAllowed = bMultiplayerAllowed;
|
|
}
|
|
} break;
|
|
case JOIN_LOAD_SEARCH_MINIMUM_TIMER_ID: {
|
|
XuiKillTimer(m_hObj, JOIN_LOAD_SEARCH_MINIMUM_TIMER_ID);
|
|
m_NetGamesListTimer.SetShow(FALSE);
|
|
m_LabelNoGames.SetShow(TRUE);
|
|
} break;
|
|
case JOIN_LOAD_SCROLL_GAME_NAMES_TIMER_ID: {
|
|
// This is called by the gameslist callback function, so isn't
|
|
// needed on a timer
|
|
// UpdateGamesListLabels();
|
|
} break;
|
|
case CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID: {
|
|
// also check for any new texture packs info being available
|
|
// for each item in the mem list, check it's in the data list
|
|
|
|
// CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
// for each iConfig, check if the data is available, and add it to
|
|
// the List, then remove it from the viConfig
|
|
|
|
for (int i = 0; i < m_iTexturePacksNotInstalled; i++) {
|
|
if (m_iConfigA[i] != -1) {
|
|
unsigned int dwBytes = 0;
|
|
std::uint8_t* pbData = NULL;
|
|
// app.DebugPrintf("Retrieving iConfig %d from
|
|
// TPD\n",m_iConfigA[i]);
|
|
|
|
app.GetTPD(m_iConfigA[i], &pbData, &dwBytes);
|
|
|
|
if (dwBytes > 0 && pbData) {
|
|
// update the games list
|
|
UpdateGamesList();
|
|
|
|
m_iConfigA[i] = -1;
|
|
}
|
|
}
|
|
}
|
|
bool bAllDone = true;
|
|
for (int i = 0; i < m_iTexturePacksNotInstalled; i++) {
|
|
if (m_iConfigA[i] != -1) {
|
|
bAllDone = false;
|
|
}
|
|
}
|
|
|
|
if (bAllDone) {
|
|
// kill this timer
|
|
XuiKillTimer(m_hObj, CHECKFORAVAILABLETEXTUREPACKS_TIMER_ID);
|
|
}
|
|
} break;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
/*
|
|
int CScene_MultiGameJoinLoad::LoadSaveDataReturned(void *pParam,bool bContinue)
|
|
{
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
if(bContinue==true)
|
|
{
|
|
bool isClientSide =
|
|
ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad());
|
|
|
|
// 4J Stu - If we only have one controller connected, then don't
|
|
show the sign-in UI again int connectedControllers = 0; for(unsigned int i = 0;
|
|
i < XUSER_MAX_COUNT; ++i)
|
|
{
|
|
if( InputManager.IsPadConnected(i) ||
|
|
ProfileManager.IsSignedIn(i) ) ++connectedControllers;
|
|
}
|
|
|
|
if(!isClientSide || connectedControllers == 1 ||
|
|
!RenderManager.IsHiDef())
|
|
{
|
|
unsigned int dwLocalUsersMask =
|
|
CGameNetworkManager::GetLocalPlayerMask(ProfileManager.GetPrimaryPad());
|
|
|
|
// No guest problems so we don't need to force a sign-in
|
|
of players here StartGameFromSave(pClass, dwLocalUsersMask);
|
|
}
|
|
else
|
|
{
|
|
ProfileManager.RequestSignInUI(false, false, false,
|
|
true, false,&CScene_MultiGameJoinLoad::StartGame_SignInReturned,
|
|
pParam,ProfileManager.GetPrimaryPad());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pClass->m_bIgnoreInput=false;
|
|
}
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
int CScene_MultiGameJoinLoad::StartGame_SignInReturned(void* pParam,
|
|
bool bContinue,
|
|
int iPad) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
if (bContinue == true) {
|
|
// It's possible that the player has not signed in - they can back out
|
|
if (ProfileManager.IsSignedIn(iPad)) {
|
|
unsigned int dwLocalUsersMask = 0;
|
|
|
|
for (unsigned int index = 0; index < XUSER_MAX_COUNT; ++index) {
|
|
if (ProfileManager.IsSignedIn(index)) {
|
|
dwLocalUsersMask |=
|
|
CGameNetworkManager::GetLocalPlayerMask(index);
|
|
}
|
|
}
|
|
StartGameFromSave(pClass, dwLocalUsersMask);
|
|
}
|
|
} else {
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// 4J Stu - Shared functionality that is the same whether we needed a quadrant
|
|
// sign-in or not
|
|
void CScene_MultiGameJoinLoad::StartGameFromSave(
|
|
CScene_MultiGameJoinLoad* pClass, DWORD dwLocalUsersMask) {
|
|
/*bool isClientSide =
|
|
ProfileManager.IsSignedInLive(ProfileManager.GetPrimaryPad()) &&
|
|
pClass->m_CheckboxOnline.IsChecked() == TRUE;
|
|
//bool isPrivate = pClass->m_CheckboxPrivate.IsChecked() == TRUE;
|
|
|
|
SenStatGameEvent(ProfileManager.GetPrimaryPad(),eTelemetryGameEvent_Load,Minecraft::GetInstance()->options->difficulty,
|
|
isClientSide, ProfileManager.IsFullVersion(), 1,0 );
|
|
|
|
g_NetworkManager.HostGame(dwLocalUsersMask,isClientSide,isPrivate,MINECRAFT_NET_MAX_PLAYERS,0);
|
|
|
|
LoadingInputParams *loadingParams = new LoadingInputParams();
|
|
loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
|
|
loadingParams->lpParam = NULL;
|
|
|
|
UIFullscreenProgressCompletionData *completionData = new
|
|
UIFullscreenProgressCompletionData(); completionData->bShowBackground=TRUE;
|
|
completionData->bShowLogo=TRUE;
|
|
completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
|
|
completionData->iPad = DEFAULT_XUI_MENU_USER;
|
|
loadingParams->completionData = completionData;
|
|
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress,
|
|
loadingParams);*/
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::DeleteSaveDataReturned(void* pParam,
|
|
bool bSuccess) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
if (bSuccess == true) {
|
|
// need to re-get the saves list and update the display
|
|
// clear the saves list
|
|
pClass->m_pSavesList->RemoveAllData();
|
|
pClass->m_iSaveInfoC = 0;
|
|
pClass->GetSaveInfo();
|
|
}
|
|
|
|
pClass->m_bIgnoreInput = false;
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::LoadLevelGen(LevelGenerationOptions* levelGen) {
|
|
// Load data from disc
|
|
// File saveFile( L"Tutorial\\Tutorial" );
|
|
// LoadSaveFromDisk(&saveFile);
|
|
|
|
// clear out the app's terrain features list
|
|
app.ClearTerrainFeaturePosition();
|
|
|
|
StorageManager.ResetSaveData();
|
|
// Make our next save default to the name of the level
|
|
StorageManager.SetSaveTitle(levelGen->getDefaultSaveName().c_str());
|
|
|
|
bool isClientSide = false;
|
|
bool isPrivate = false;
|
|
int maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
|
|
|
if (app.GetTutorialMode()) {
|
|
isClientSide = false;
|
|
maxPlayers = 4;
|
|
}
|
|
|
|
g_NetworkManager.HostGame(0, isClientSide, isPrivate, maxPlayers, 0);
|
|
|
|
NetworkGameInitData* param = new NetworkGameInitData();
|
|
param->seed = 0;
|
|
param->saveData = NULL;
|
|
param->settings = app.GetGameHostOption(eGameHostOption_Tutorial);
|
|
param->levelGen = levelGen;
|
|
|
|
if (levelGen->requiresTexturePack()) {
|
|
param->texturePackId = levelGen->getRequiredTexturePackId();
|
|
|
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
|
pMinecraft->skins->selectTexturePackById(param->texturePackId);
|
|
// pMinecraft->skins->updateUI();
|
|
}
|
|
|
|
LoadingInputParams* loadingParams = new LoadingInputParams();
|
|
loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
|
|
loadingParams->lpParam = param;
|
|
|
|
UIFullscreenProgressCompletionData* completionData =
|
|
new UIFullscreenProgressCompletionData();
|
|
completionData->bShowBackground = TRUE;
|
|
completionData->bShowLogo = TRUE;
|
|
completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
|
|
completionData->iPad = DEFAULT_XUI_MENU_USER;
|
|
loadingParams->completionData = completionData;
|
|
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),
|
|
eUIScene_FullscreenProgress, loadingParams);
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::LoadSaveFromDisk(File* saveFile) {
|
|
// we'll only be coming in here when the tutorial is loaded now
|
|
|
|
StorageManager.ResetSaveData();
|
|
|
|
// Make our next save default to the name of the level
|
|
StorageManager.SetSaveTitle(saveFile->getName().c_str());
|
|
|
|
__int64 fileSize = saveFile->length();
|
|
FileInputStream fis(*saveFile);
|
|
byteArray ba(fileSize);
|
|
fis.read(ba);
|
|
fis.close();
|
|
|
|
bool isClientSide = false;
|
|
bool isPrivate = false;
|
|
int maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
|
|
|
|
if (app.GetTutorialMode()) {
|
|
isClientSide = false;
|
|
maxPlayers = 4;
|
|
}
|
|
|
|
app.SetGameHostOption(eGameHostOption_GameType,
|
|
GameType::CREATIVE->getId());
|
|
|
|
g_NetworkManager.HostGame(0, isClientSide, isPrivate, maxPlayers, 0);
|
|
|
|
LoadSaveDataThreadParam* saveData =
|
|
new LoadSaveDataThreadParam(ba.data, ba.length, saveFile->getName());
|
|
|
|
NetworkGameInitData* param = new NetworkGameInitData();
|
|
param->seed = 0;
|
|
param->saveData = saveData;
|
|
param->settings = app.GetGameHostOption(eGameHostOption_All);
|
|
|
|
LoadingInputParams* loadingParams = new LoadingInputParams();
|
|
loadingParams->func = &CGameNetworkManager::RunNetworkGameThreadProc;
|
|
loadingParams->lpParam = param;
|
|
|
|
UIFullscreenProgressCompletionData* completionData =
|
|
new UIFullscreenProgressCompletionData();
|
|
completionData->bShowBackground = TRUE;
|
|
completionData->bShowLogo = TRUE;
|
|
completionData->type = e_ProgressCompletion_CloseAllPlayersUIScenes;
|
|
completionData->iPad = DEFAULT_XUI_MENU_USER;
|
|
loadingParams->completionData = completionData;
|
|
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),
|
|
eUIScene_FullscreenProgress, loadingParams);
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::DeleteSaveDialogReturned(
|
|
void* pParam, int iPad, C4JStorage::EMessageResult result) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
// results switched for this dialog
|
|
if (result == C4JStorage::EMessage_ResultDecline) {
|
|
if (app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled()) {
|
|
pClass->m_bIgnoreInput = false;
|
|
} else {
|
|
XCONTENT_DATA XContentData;
|
|
StorageManager.GetSaveCacheFileInfo(
|
|
pClass->m_iChangingSaveGameInfoIndex -
|
|
pClass->m_iDefaultButtonsC,
|
|
XContentData);
|
|
StorageManager.DeleteSaveData(
|
|
&XContentData, CScene_MultiGameJoinLoad::DeleteSaveDataReturned,
|
|
pClass);
|
|
pClass->m_SavesListTimer.SetShow(TRUE);
|
|
}
|
|
} else {
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::SaveTransferDialogReturned(
|
|
void* pParam, int iPad, C4JStorage::EMessageResult result) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
// results switched for this dialog
|
|
if (result == C4JStorage::EMessage_ResultAccept) {
|
|
// upload the save
|
|
|
|
// first load the save
|
|
int iIndex =
|
|
pClass->m_pSavesList->GetData(pClass->m_pSavesList->GetCurSel())
|
|
.iIndex -
|
|
pClass->m_iDefaultButtonsC;
|
|
XCONTENT_DATA ContentData;
|
|
|
|
// 4J-PB - ensure we've switched to the right title group id for
|
|
// uploading to
|
|
app.TMSPP_SetTitleGroupID(SAVETRANSFER_GROUP_ID);
|
|
StorageManager.GetSaveCacheFileInfo(iIndex, ContentData);
|
|
C4JStorage::ELoadGameStatus eLoadStatus = StorageManager.LoadSaveData(
|
|
&ContentData, CScene_MultiGameJoinLoad::LoadSaveDataReturned,
|
|
pClass);
|
|
|
|
pClass->m_bIgnoreInput = false;
|
|
} else {
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::UploadSaveForXboxOneThreadProc(
|
|
LPVOID lpParameter) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)lpParameter;
|
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
|
|
|
pMinecraft->progressRenderer->progressStart(IDS_SAVE_TRANSFER_TITLE);
|
|
pMinecraft->progressRenderer->progressStage(IDS_SAVE_TRANSFER_UPLOADING);
|
|
|
|
// Delete the marker file
|
|
DeleteFile(pClass, "completemarker");
|
|
if (!WaitForTransferComplete(pClass)) return 0;
|
|
|
|
// Upload the save data
|
|
{
|
|
unsigned int uiSaveBytes;
|
|
uiSaveBytes = StorageManager.GetSaveSize();
|
|
pClass->m_pbSaveTransferData = new BYTE[uiSaveBytes];
|
|
|
|
StorageManager.GetSaveData(pClass->m_pbSaveTransferData, &uiSaveBytes);
|
|
|
|
app.DebugPrintf("Uploading save data (%d bytes)\n", uiSaveBytes);
|
|
UploadFile(pClass, "savedata", pClass->m_pbSaveTransferData,
|
|
uiSaveBytes);
|
|
}
|
|
|
|
if (!WaitForTransferComplete(pClass)) return 0;
|
|
if (pClass->m_bTransferFail) {
|
|
// something went wrong, user has been informed
|
|
pMinecraft->progressRenderer->progressStage(
|
|
IDS_SAVE_TRANSFER_UPLOADFAILED);
|
|
return 0;
|
|
}
|
|
|
|
// Upload the metadata and thumbnail
|
|
{
|
|
ByteArrayOutputStream baos;
|
|
DataOutputStream dos(&baos);
|
|
|
|
LPCWSTR title = StorageManager.GetSaveTitle();
|
|
dos.writeUTF(title);
|
|
|
|
char szUniqueMapName[14];
|
|
StorageManager.GetSaveUniqueFilename(szUniqueMapName);
|
|
dos.writeUTF(convStringToWstring(szUniqueMapName));
|
|
|
|
{
|
|
// set the save icon
|
|
PBYTE pbImageData = NULL;
|
|
DWORD dwImageBytes = 0;
|
|
XCONTENT_DATA XContentData;
|
|
int iIndex =
|
|
pClass->m_pSavesList->GetData(pClass->m_pSavesList->GetCurSel())
|
|
.iIndex -
|
|
pClass->m_iDefaultButtonsC;
|
|
StorageManager.GetSaveCacheFileInfo(iIndex, XContentData);
|
|
StorageManager.GetSaveCacheFileInfo(iIndex, &pbImageData,
|
|
&dwImageBytes);
|
|
|
|
// 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
|
|
if (pbImageData == NULL) {
|
|
DWORD dwResult = XContentGetThumbnail(
|
|
ProfileManager.GetPrimaryPad(), &XContentData, NULL,
|
|
&dwImageBytes, NULL);
|
|
if (dwResult == ERROR_SUCCESS) {
|
|
pClass->m_pbSaveTransferData = new BYTE[dwImageBytes];
|
|
pbImageData =
|
|
pClass
|
|
->m_pbSaveTransferData; // Copy pointer so that we
|
|
// can use the same name as
|
|
// the library owned one,
|
|
// but m_pbSaveTransferData
|
|
// will get deleted when
|
|
// done
|
|
XContentGetThumbnail(ProfileManager.GetPrimaryPad(),
|
|
&XContentData, pbImageData,
|
|
&dwImageBytes, NULL);
|
|
}
|
|
}
|
|
|
|
dos.writeInt(dwImageBytes);
|
|
|
|
byteArray ba(pbImageData, dwImageBytes);
|
|
dos.write(ba);
|
|
}
|
|
|
|
pClass->m_pbSaveTransferData = new BYTE[baos.size()];
|
|
memcpy(pClass->m_pbSaveTransferData, baos.buf.data, baos.size());
|
|
|
|
app.DebugPrintf("Uploading meta data (%d bytes)\n", baos.size());
|
|
UploadFile(pClass, "metadata", pClass->m_pbSaveTransferData,
|
|
baos.size());
|
|
}
|
|
|
|
// Wait for metadata and thumbnail
|
|
if (!WaitForTransferComplete(pClass)) return 0;
|
|
if (pClass->m_bTransferFail) {
|
|
// something went wrong, user has been informed
|
|
pMinecraft->progressRenderer->progressStage(
|
|
IDS_SAVE_TRANSFER_UPLOADFAILED);
|
|
return 0;
|
|
}
|
|
|
|
// Upload the marker file
|
|
{
|
|
char singleByteData[1] = {1};
|
|
app.DebugPrintf("Uploading marker (%d bytes)\n", 1);
|
|
UploadFile(pClass, "completemarker", &singleByteData, 1);
|
|
}
|
|
|
|
// Wait for marker
|
|
if (!WaitForTransferComplete(pClass)) return 0;
|
|
if (pClass->m_bTransferFail) {
|
|
// something went wrong, user has been informed
|
|
pMinecraft->progressRenderer->progressStage(
|
|
IDS_SAVE_TRANSFER_UPLOADFAILED);
|
|
|
|
return 0;
|
|
}
|
|
// change text for completion confirmation
|
|
pMinecraft->progressRenderer->progressStage(
|
|
IDS_SAVE_TRANSFER_UPLOADCOMPLETE);
|
|
|
|
// done
|
|
return 0;
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::DeleteFile(CScene_MultiGameJoinLoad* pClass,
|
|
char* filename) {
|
|
pClass->m_fProgress = 0.0f;
|
|
pClass->m_bTransferComplete = false;
|
|
|
|
C4JStorage::ETMSStatus result = StorageManager.TMSPP_DeleteFile(
|
|
ProfileManager.GetPrimaryPad(), filename,
|
|
C4JStorage::TMS_FILETYPE_BINARY,
|
|
&CScene_MultiGameJoinLoad::DeleteComplete, pClass, NULL);
|
|
|
|
if (result != C4JStorage::ETMSStatus_DeleteInProgress) {
|
|
DeleteComplete(pClass, ProfileManager.GetPrimaryPad(), -1);
|
|
}
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::UploadFile(CScene_MultiGameJoinLoad* pClass,
|
|
char* filename, LPVOID data,
|
|
DWORD size) {
|
|
pClass->m_fProgress = 0.0f;
|
|
pClass->m_bTransferComplete = false;
|
|
|
|
C4JStorage::ETMSStatus result = StorageManager.TMSPP_WriteFileWithProgress(
|
|
ProfileManager.GetPrimaryPad(), C4JStorage::eGlobalStorage_TitleUser,
|
|
C4JStorage::TMS_FILETYPE_BINARY, C4JStorage::TMS_UGCTYPE_NONE, filename,
|
|
(CHAR*)data, size, &CScene_MultiGameJoinLoad::TransferComplete, pClass,
|
|
0, &CScene_MultiGameJoinLoad::Progress, pClass);
|
|
|
|
#ifdef _DEBUG_MENUS_ENABLED
|
|
if (app.GetWriteSavesToFolderEnabled()) {
|
|
File targetFileDir(L"GAME:\\FakeTMSPP");
|
|
if (!targetFileDir.exists()) targetFileDir.mkdir();
|
|
std::string path = string(wstringtofilename(targetFileDir.getPath()))
|
|
.append("\\")
|
|
.append(filename);
|
|
HANDLE hSaveFile =
|
|
CreateFile(path.c_str(), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
|
|
FILE_FLAG_RANDOM_ACCESS, NULL);
|
|
|
|
DWORD numberOfBytesWritten = 0;
|
|
WriteFile(hSaveFile, data, size, &numberOfBytesWritten, NULL);
|
|
assert(numberOfBytesWritten == size);
|
|
|
|
CloseHandle(hSaveFile);
|
|
}
|
|
#endif
|
|
|
|
if (result != C4JStorage::ETMSStatus_WriteInProgress) {
|
|
TransferComplete(pClass, ProfileManager.GetPrimaryPad(), -1);
|
|
}
|
|
}
|
|
|
|
bool CScene_MultiGameJoinLoad::WaitForTransferComplete(
|
|
CScene_MultiGameJoinLoad* pClass) {
|
|
Minecraft* pMinecraft = Minecraft::GetInstance();
|
|
// loop until complete
|
|
while (pClass->m_bTransferComplete == false) {
|
|
// check for a cancel
|
|
if (pClass->m_bSaveTransferInProgress == false) {
|
|
// cancelled
|
|
return false;
|
|
}
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
|
// update the progress
|
|
pMinecraft->progressRenderer->progressStagePercentage(
|
|
(unsigned int)(pClass->m_fProgress * 100.0f));
|
|
}
|
|
|
|
// was there a transfer error?
|
|
|
|
return true;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::SaveOptionsDialogReturned(
|
|
void* pParam, int iPad, C4JStorage::EMessageResult result) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
// results switched for this dialog
|
|
// EMessage_ResultAccept means cancel
|
|
if (result == C4JStorage::EMessage_ResultDecline ||
|
|
result == C4JStorage::EMessage_ResultThirdOption) {
|
|
if (result == C4JStorage::EMessage_ResultDecline) // rename
|
|
{
|
|
ZeroMemory(pClass->m_wchNewName,
|
|
sizeof(WCHAR) * XCONTENT_MAX_DISPLAYNAME_LENGTH);
|
|
// bring up a keyboard
|
|
InputManager.RequestKeyboard(
|
|
IDS_RENAME_WORLD_TITLE, L"", IDS_RENAME_WORLD_TEXT, iPad,
|
|
pClass->m_wchNewName, XCONTENT_MAX_DISPLAYNAME_LENGTH,
|
|
&CScene_MultiGameJoinLoad::KeyboardReturned, pClass,
|
|
C_4JInput::EKeyboardMode_Default, app.GetStringTable());
|
|
} else // delete
|
|
{
|
|
// delete the save game
|
|
// Have to ask the player if they are sure they want to delete this
|
|
// game
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_TOOLTIPS_DELETESAVE, IDS_TEXT_DELETE_SAVE, uiIDA, 2, iPad,
|
|
&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned, pClass,
|
|
app.GetStringTable());
|
|
// pClass->m_bIgnoreInput=false;
|
|
}
|
|
} else {
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::LoadSaveDataReturned(void* pParam,
|
|
bool bContinue) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
if (bContinue == true) {
|
|
pClass->m_bSaveTransferInProgress = true;
|
|
LoadingInputParams* loadingParams = new LoadingInputParams();
|
|
loadingParams->func =
|
|
&CScene_MultiGameJoinLoad::UploadSaveForXboxOneThreadProc;
|
|
loadingParams->lpParam = (LPVOID)pParam;
|
|
|
|
UIFullscreenProgressCompletionData* completionData =
|
|
new UIFullscreenProgressCompletionData();
|
|
completionData->bShowBackground = TRUE;
|
|
completionData->bShowLogo = TRUE;
|
|
completionData->type = e_ProgressCompletion_NavigateBack;
|
|
completionData->iPad = DEFAULT_XUI_MENU_USER;
|
|
completionData->bRequiresUserAction = TRUE;
|
|
loadingParams->completionData = completionData;
|
|
|
|
loadingParams->cancelFunc =
|
|
&CScene_MultiGameJoinLoad::CancelSaveUploadCallback;
|
|
loadingParams->completeFunc =
|
|
&CScene_MultiGameJoinLoad::SaveUploadCompleteCallback;
|
|
loadingParams->m_cancelFuncParam = pClass;
|
|
loadingParams->m_completeFuncParam = pClass;
|
|
loadingParams->cancelText = IDS_TOOLTIPS_CANCEL;
|
|
|
|
app.NavigateToScene(ProfileManager.GetPrimaryPad(),
|
|
eUIScene_FullscreenProgress, loadingParams);
|
|
} else {
|
|
// switch back to the normal title group id
|
|
app.TMSPP_SetTitleGroupID(GROUP_ID);
|
|
|
|
// the save is corrupt!
|
|
|
|
pClass->SetShow(TRUE);
|
|
pClass->m_bIgnoreInput = false;
|
|
|
|
// give the option to delete the save
|
|
unsigned int uiIDA[2];
|
|
uiIDA[0] = IDS_CONFIRM_CANCEL;
|
|
uiIDA[1] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE, IDS_CORRUPT_OR_DAMAGED_SAVE_TEXT,
|
|
uiIDA, 2, pClass->m_iPad,
|
|
&CScene_MultiGameJoinLoad::DeleteSaveDialogReturned, pClass,
|
|
app.GetStringTable());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::Progress(void* pParam, float fProgress) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
app.DebugPrintf("Progress - %f\n", fProgress);
|
|
pClass->m_fProgress = fProgress;
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::TransferComplete(void* pParam, int iPad,
|
|
int iResult) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
delete[] pClass->m_pbSaveTransferData;
|
|
pClass->m_pbSaveTransferData = NULL;
|
|
if (iResult != 0) {
|
|
// There was a transfer fail
|
|
// Display a dialog
|
|
unsigned int uiIDA[1];
|
|
uiIDA[0] = IDS_CONFIRM_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_SAVE_TRANSFER_TITLE, IDS_SAVE_TRANSFER_UPLOADFAILED, uiIDA, 1,
|
|
ProfileManager.GetPrimaryPad(), NULL, NULL, app.GetStringTable());
|
|
pClass->m_bTransferFail = true;
|
|
} else {
|
|
pClass->m_bTransferFail = false;
|
|
}
|
|
pClass->m_bTransferComplete = true;
|
|
// pClass->m_bSaveTransferInProgress=false;
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::DeleteComplete(void* pParam, int iPad,
|
|
int iResult) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
pClass->m_bTransferComplete = true;
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::KeyboardReturned(void* pParam, bool bSet) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
HRESULT hr = S_OK;
|
|
|
|
// if the user has left the name empty, treat this as backing out
|
|
if ((pClass->m_wchNewName[0] != 0) && bSet) {
|
|
#ifdef _XBOX
|
|
XCONTENT_DATA XContentData;
|
|
StorageManager.GetSaveCacheFileInfo(
|
|
pClass->m_iChangingSaveGameInfoIndex - pClass->m_iDefaultButtonsC,
|
|
XContentData);
|
|
|
|
C4JStorage::ELoadGameStatus eLoadStatus = StorageManager.LoadSaveData(
|
|
&XContentData,
|
|
CScene_MultiGameJoinLoad::LoadSaveDataForRenameReturned, pClass);
|
|
|
|
if (eLoadStatus == C4JStorage::ELoadGame_DeviceRemoved) {
|
|
// disable saving
|
|
StorageManager.SetSaveDisabled(true);
|
|
StorageManager.SetSaveDeviceSelected(ProfileManager.GetPrimaryPad(),
|
|
false);
|
|
unsigned int uiIDA[1];
|
|
uiIDA[0] = IDS_OK;
|
|
StorageManager.RequestMessageBox(
|
|
IDS_STORAGEDEVICEPROBLEM_TITLE, IDS_FAILED_TO_LOADSAVE_TEXT,
|
|
uiIDA, 1, ProfileManager.GetPrimaryPad(),
|
|
&CScene_MultiGameJoinLoad::DeviceRemovedDialogReturned, pClass);
|
|
}
|
|
#else
|
|
// rename the save
|
|
|
|
#endif
|
|
} else {
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::LoadSaveDataForRenameReturned(void* pParam,
|
|
bool bContinue) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
#ifdef _XBOX
|
|
if (bContinue == true) {
|
|
// set the save icon
|
|
PBYTE pbImageData = NULL;
|
|
DWORD dwImageBytes = 0;
|
|
HXUIBRUSH hXuiBrush;
|
|
XCONTENT_DATA XContentData;
|
|
StorageManager.GetSaveCacheFileInfo(
|
|
pClass->m_iChangingSaveGameInfoIndex - pClass->m_iDefaultButtonsC,
|
|
XContentData);
|
|
StorageManager.GetSaveCacheFileInfo(
|
|
pClass->m_iChangingSaveGameInfoIndex - pClass->m_iDefaultButtonsC,
|
|
&pbImageData, &dwImageBytes);
|
|
|
|
// 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
|
|
if (pbImageData == NULL) {
|
|
DWORD dwResult =
|
|
XContentGetThumbnail(ProfileManager.GetPrimaryPad(),
|
|
&XContentData, NULL, &dwImageBytes, NULL);
|
|
if (dwResult == ERROR_SUCCESS) {
|
|
pbImageData = new BYTE[dwImageBytes];
|
|
XContentGetThumbnail(ProfileManager.GetPrimaryPad(),
|
|
&XContentData, pbImageData, &dwImageBytes,
|
|
NULL);
|
|
XuiCreateTextureBrushFromMemory(pbImageData, dwImageBytes,
|
|
&hXuiBrush);
|
|
}
|
|
} else {
|
|
XuiCreateTextureBrushFromMemory(pbImageData, dwImageBytes,
|
|
&hXuiBrush);
|
|
}
|
|
// save the data with this icon
|
|
StorageManager.CopySaveDataToNewSave(
|
|
pbImageData, dwImageBytes, pClass->m_wchNewName,
|
|
&CScene_MultiGameJoinLoad::CopySaveReturned, pClass);
|
|
} else
|
|
#endif
|
|
{
|
|
// pClass->SetShow( TRUE );
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::CopySaveReturned(void* pParam, bool bResult) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
#ifdef _XBOX
|
|
if (bResult) {
|
|
// and delete the old save
|
|
XCONTENT_DATA XContentData;
|
|
StorageManager.GetSaveCacheFileInfo(
|
|
pClass->m_iChangingSaveGameInfoIndex - pClass->m_iDefaultButtonsC,
|
|
XContentData);
|
|
StorageManager.DeleteSaveData(
|
|
&XContentData, CScene_MultiGameJoinLoad::DeleteSaveDataReturned,
|
|
pClass);
|
|
pClass->m_SavesListTimer.SetShow(TRUE);
|
|
} else
|
|
#endif
|
|
{
|
|
// pClass->SetShow( TRUE );
|
|
pClass->m_bIgnoreInput = false;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int CScene_MultiGameJoinLoad::TexturePackDialogReturned(
|
|
void* pParam, int iPad, C4JStorage::EMessageResult result) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
|
|
// Exit with or without saving
|
|
// Decline means install full version of the texture pack in this dialog
|
|
if (result == C4JStorage::EMessage_ResultDecline ||
|
|
result == C4JStorage::EMessage_ResultAccept) {
|
|
// we need to enable background downloading for the DLC
|
|
XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_ALWAYS_ALLOW);
|
|
|
|
ULONGLONG ullOfferID_Full;
|
|
ULONGLONG ullIndexA[1];
|
|
app.GetDLCFullOfferIDForPackID(
|
|
pClass->m_initData->selectedSession->data.texturePackParentId,
|
|
&ullOfferID_Full);
|
|
|
|
if (result == C4JStorage::EMessage_ResultAccept) // Full version
|
|
{
|
|
ullIndexA[0] = ullOfferID_Full;
|
|
StorageManager.InstallOffer(1, ullIndexA, NULL, NULL);
|
|
|
|
} else // trial version
|
|
{
|
|
// if there is no trial version, this is a Cancel
|
|
DLC_INFO* pDLCInfo = app.GetDLCInfoForFullOfferID(ullOfferID_Full);
|
|
if (pDLCInfo->ullOfferID_Trial != 0LL) {
|
|
ullIndexA[0] = pDLCInfo->ullOfferID_Trial;
|
|
StorageManager.InstallOffer(1, ullIndexA, NULL, NULL);
|
|
}
|
|
}
|
|
}
|
|
pClass->m_bIgnoreInput = false;
|
|
return 0;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnCustomMessage_DLCInstalled() {
|
|
// mounted DLC may have changed
|
|
|
|
if (app.StartInstallDLCProcess(m_iPad) == false) {
|
|
// not doing a mount, so re-enable input
|
|
m_bIgnoreInput = false;
|
|
} else {
|
|
m_bIgnoreInput = true;
|
|
// clear out the saves list and re-fill
|
|
|
|
m_pSavesList->RemoveAllData();
|
|
m_SavesListTimer.SetShow(TRUE);
|
|
}
|
|
// this will send a CustomMessage_DLCMountingComplete when done
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CScene_MultiGameJoinLoad::OnCustomMessage_DLCMountingComplete() {
|
|
void* pObj;
|
|
XuiObjectFromHandle(m_SavesList, &pObj);
|
|
m_pSavesList = (CXuiCtrl4JList*)pObj;
|
|
|
|
m_iChangingSaveGameInfoIndex = 0;
|
|
|
|
m_generators = app.getLevelGenerators();
|
|
m_iDefaultButtonsC = 0;
|
|
m_iMashUpButtonsC = 0;
|
|
XPARTY_USER_LIST partyList;
|
|
|
|
if ((XPartyGetUserList(&partyList) != XPARTY_E_NOT_IN_PARTY) &&
|
|
(partyList.dwUserCount > 1)) {
|
|
m_bInParty = true;
|
|
} else {
|
|
m_bInParty = false;
|
|
}
|
|
|
|
int iLB = -1;
|
|
|
|
int iY = -1;
|
|
if (DoesSavesListHaveFocus()) {
|
|
if (ProfileManager.IsSignedInLive(m_iPad)) {
|
|
iY = IDS_TOOLTIPS_UPLOAD_SAVE_FOR_XBOXONE;
|
|
}
|
|
}
|
|
if (m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
// check if we're in the trial version
|
|
if (ProfileManager.IsFullVersion() == false) {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, -1, -1, -1, -1, iLB);
|
|
|
|
AddDefaultButtons();
|
|
|
|
m_pSavesList->SetCurSelVisible(0);
|
|
} else if (StorageManager.GetSaveDisabled()) {
|
|
if (StorageManager.GetSaveDeviceSelected(m_iPad)) {
|
|
// saving is disabled, but we should still be able to load from a
|
|
// selected save device
|
|
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_CHANGEDEVICE, iY, -1,
|
|
-1, iLB, IDS_TOOLTIPS_DELETESAVE);
|
|
|
|
GetSaveInfo();
|
|
} else {
|
|
ui.SetTooltips(DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT,
|
|
IDS_TOOLTIPS_BACK, IDS_TOOLTIPS_SELECTDEVICE, iY, -1,
|
|
-1, iLB);
|
|
|
|
AddDefaultButtons();
|
|
m_SavesListTimer.SetShow(FALSE);
|
|
|
|
m_pSavesList->SetCurSelVisible(0);
|
|
}
|
|
} 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();
|
|
ui.SetTooltips(
|
|
DEFAULT_XUI_MENU_USER, IDS_TOOLTIPS_SELECT, IDS_TOOLTIPS_BACK,
|
|
IDS_TOOLTIPS_CHANGEDEVICE, iY, -1, -1, -1,
|
|
bCanRename ? IDS_TOOLTIPS_SAVEOPTIONS : IDS_TOOLTIPS_DELETESAVE);
|
|
|
|
GetSaveInfo();
|
|
}
|
|
|
|
m_bIgnoreInput = false;
|
|
app.m_dlcManager.checkForCorruptDLCAndAlert();
|
|
return S_OK;
|
|
}
|
|
|
|
/*
|
|
void CScene_MultiGameJoinLoad::UpdateTooltips()
|
|
{
|
|
int iA=IDS_TOOLTIPS_SELECT;
|
|
int iB=IDS_TOOLTIPS_BACK;
|
|
int iX=-1;
|
|
int iY=-1
|
|
int iLB = -1;
|
|
XPARTY_USER_LIST partyList;
|
|
|
|
if((XPartyGetUserList( &partyList ) != XPARTY_E_NOT_IN_PARTY ) &&
|
|
(partyList.dwUserCount>1))
|
|
{
|
|
m_bInParty=true;
|
|
}
|
|
else
|
|
{
|
|
m_bInParty=false;
|
|
}
|
|
|
|
if(m_bInParty) iLB = IDS_TOOLTIPS_PARTY_GAMES;
|
|
|
|
if(ProfileManager.IsFullVersion()==false)
|
|
{
|
|
ui.SetTooltips( DEFAULT_XUI_MENU_USER,
|
|
IDS_TOOLTIPS_SELECT,IDS_TOOLTIPS_BACK, -1, -1, -1, -1,iLB);
|
|
}
|
|
else if(StorageManager.GetSaveDisabled())
|
|
{
|
|
if(StorageManager.GetSaveDeviceSelected(m_iPad))
|
|
{
|
|
// saving is disabled, but we should still be able to
|
|
load from a selected save device iX=IDS_TOOLTIPS_CHANGEDEVICE;
|
|
iRB=IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
else
|
|
{
|
|
iX=IDS_TOOLTIPS_SELECTDEVICE;
|
|
}
|
|
}
|
|
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();
|
|
|
|
if(bCanRename)
|
|
{
|
|
iRB=IDS_TOOLTIPS_SAVEOPTIONS;
|
|
}
|
|
else
|
|
{
|
|
iRB=IDS_TOOLTIPS_DELETESAVE;
|
|
}
|
|
}
|
|
|
|
ui.SetTooltips( DEFAULT_XUI_MENU_USER, iA,iB, iX, iY, iLT, iRT,iLB,
|
|
iRB);
|
|
}
|
|
*/
|
|
|
|
#ifdef _XBOX
|
|
bool CScene_MultiGameJoinLoad::GetSavesInfoCallback(
|
|
LPVOID pParam, int iTotalSaveInfoC, C4JStorage::CACHEINFOSTRUCT* InfoA,
|
|
int iPad, HRESULT hResult) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)pParam;
|
|
CXuiCtrl4JList::LIST_ITEM_INFO ListInfo;
|
|
PBYTE pbImageData = (PBYTE)InfoA;
|
|
PBYTE pbCurrentImagePtr;
|
|
HXUIBRUSH hXuiBrush;
|
|
HRESULT hr;
|
|
|
|
// move the image data pointer to the right place
|
|
if (iTotalSaveInfoC != 0) {
|
|
pbImageData += sizeof(C4JStorage::CACHEINFOSTRUCT) * iTotalSaveInfoC;
|
|
}
|
|
|
|
pClass->m_SavesListTimer.SetShow(FALSE);
|
|
pClass->m_SavesList.SetEnable(TRUE);
|
|
|
|
pClass->AddDefaultButtons();
|
|
|
|
for (int i = 0; i < iTotalSaveInfoC; i++) {
|
|
ZeroMemory(&ListInfo, sizeof(CXuiCtrl4JList::LIST_ITEM_INFO));
|
|
// Add these to the save list
|
|
if (!(app.DebugSettingsOn() && app.GetLoadSavesFromFolderEnabled())) {
|
|
// if the save is corrupt, display this instead of the title
|
|
if (InfoA[i].dwImageBytes == 0) {
|
|
ListInfo.pwszText =
|
|
app.GetString(IDS_CORRUPT_OR_DAMAGED_SAVE_TITLE);
|
|
ListInfo.bIsDamaged = true;
|
|
} else {
|
|
ListInfo.pwszText = InfoA[i].wchDisplayName;
|
|
ListInfo.bIsDamaged = false;
|
|
}
|
|
ListInfo.fEnabled = TRUE;
|
|
ListInfo.iData = -1;
|
|
|
|
pClass->m_pSavesList->AddData(ListInfo, -1);
|
|
|
|
// update the graphic on the list item
|
|
|
|
// if there is no thumbnail, this is a corrupt file
|
|
if (InfoA[i].dwImageBytes != 0) {
|
|
pbCurrentImagePtr = pbImageData + InfoA[i].dwImageOffset;
|
|
hr = XuiCreateTextureBrushFromMemory(
|
|
pbCurrentImagePtr, InfoA[i].dwImageBytes, &hXuiBrush);
|
|
pClass->m_pSavesList->UpdateGraphic(
|
|
i + pClass->m_iDefaultButtonsC, hXuiBrush);
|
|
} else {
|
|
// we could put in a damaged save icon here
|
|
constexpr int LOCATOR_SIZE =
|
|
256; // Use this to allocate space to hold a
|
|
// ResourceLocator string
|
|
WCHAR szResourceLocator[LOCATOR_SIZE];
|
|
const ULONG_PTR c_ModuleHandle =
|
|
(ULONG_PTR)GetModuleHandle(NULL);
|
|
|
|
swprintf(szResourceLocator, LOCATOR_SIZE,
|
|
L"section://%X,%ls#%ls", c_ModuleHandle, L"media",
|
|
L"media/Graphics/MinecraftBrokenIcon.png");
|
|
|
|
XuiCreateTextureBrush(szResourceLocator, &hXuiBrush);
|
|
pClass->m_pSavesList->UpdateGraphic(
|
|
i + pClass->m_iDefaultButtonsC, hXuiBrush);
|
|
}
|
|
}
|
|
}
|
|
|
|
pClass->m_iSaveInfoC = iTotalSaveInfoC;
|
|
|
|
// If there are some saves, then set the focus to be on the most recent one,
|
|
// which will be the first one after the create and tutorial
|
|
if (iTotalSaveInfoC > 0) {
|
|
pClass->m_pSavesList->SetCurSelVisible(pClass->m_iDefaultButtonsC);
|
|
pClass->m_bReady = true;
|
|
}
|
|
|
|
pClass->m_bRetrievingSaveInfo = false;
|
|
|
|
// It's possible that the games list is updated but we haven't displayed it
|
|
// yet as we were still waiting on saves list to load This is to fix a bug
|
|
// where joining a game before the saves list has loaded causes a crash when
|
|
// this callback is called as the scene no longer exists
|
|
pClass->UpdateGamesList();
|
|
|
|
// Fix for #45154 - Frontend: DLC: Content can only be downloaded from the
|
|
// frontend if you have not joined/exited multiplayer
|
|
XBackgroundDownloadSetMode(XBACKGROUND_DOWNLOAD_MODE_AUTO);
|
|
|
|
return false;
|
|
}
|
|
#else
|
|
int CScene_MultiGameJoinLoad::GetSavesInfoCallback(LPVOID lpParam, const bool) {
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
void CScene_MultiGameJoinLoad::CancelSaveUploadCallback(LPVOID lpParam) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)lpParam;
|
|
|
|
StorageManager.TMSPP_CancelWriteFileWithProgress(pClass->m_iPad);
|
|
|
|
pClass->m_bSaveTransferInProgress = false;
|
|
|
|
// change back to the normal title group id
|
|
app.TMSPP_SetTitleGroupID(GROUP_ID);
|
|
// app.getRemoteStorage()->abort();
|
|
// pClass->m_eSaveUploadState = eSaveUpload_Idle;
|
|
|
|
unsigned int uiIDA[1] = {IDS_CONFIRM_OK};
|
|
ui.RequestMessageBox(IDS_XBONE_CANCEL_UPLOAD_TITLE,
|
|
IDS_XBONE_CANCEL_UPLOAD_TEXT, uiIDA, 1, pClass->m_iPad,
|
|
NULL, NULL, app.GetStringTable());
|
|
}
|
|
|
|
void CScene_MultiGameJoinLoad::SaveUploadCompleteCallback(LPVOID lpParam) {
|
|
CScene_MultiGameJoinLoad* pClass = (CScene_MultiGameJoinLoad*)lpParam;
|
|
|
|
pClass->m_bSaveTransferInProgress = false;
|
|
// change back to the normal title group id
|
|
app.TMSPP_SetTitleGroupID(GROUP_ID);
|
|
// app.getRemoteStorage()->abort();
|
|
// pClass->m_eSaveUploadState = eSaveUpload_Idle;
|
|
}
|