From 5a8b93829bb7bf43a2af258a931336eeb0365c77 Mon Sep 17 00:00:00 2001 From: Fireblade <3+fireblade@noreply.neolegacy.dev> Date: Thu, 23 Jul 2026 22:22:43 -0400 Subject: [PATCH] feat: modern autosave --- Minecraft.Client/ClientConnection.cpp | 29 +-- Minecraft.Client/Common/Consoles_App.cpp | 108 +++++++---- Minecraft.Client/Common/Consoles_App.h | 2 + .../Common/UI/IUIScene_PauseMenu.cpp | 46 +++-- .../UI/UIComponent_PressStartToPlay.cpp | 24 +++ .../Common/UI/UIComponent_PressStartToPlay.h | 1 + Minecraft.Client/Common/UI/UIController.cpp | 14 +- .../Common/UI/UIScene_DeathMenu.cpp | 21 ++- .../Common/UI/UIScene_PauseMenu.cpp | 174 ++++++++++-------- .../Common/UI/UIScene_SettingsOptionsMenu.cpp | 29 ++- .../Windows64Media/loc/stringsGeneric.xml | 4 + .../loc/stringsPlatformSpecific.xml | 16 +- 12 files changed, 300 insertions(+), 168 deletions(-) diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp index 6717114c..36e1d981 100644 --- a/Minecraft.Client/ClientConnection.cpp +++ b/Minecraft.Client/ClientConnection.cpp @@ -4180,14 +4180,16 @@ int ClientConnection::HostDisconnectReturned(void *pParam,int iPad,C4JStorage::E } } -#if defined(_XBOX_ONE) || defined(__ORBIS__) + const int controlType = app.GetGameSettings(iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + // Give the player the option to save their game // does the save exist? bool bSaveExists; StorageManager.DoesSaveExist(&bSaveExists); // 4J-PB - we check if the save exists inside the libs // we need to ask if they are sure they want to overwrite the existing game - if(bSaveExists && StorageManager.GetSaveDisabled()) + if(bSaveExists && (!consoleAutosave || StorageManager.GetSaveDisabled())) { UINT uiIDA[2]; uiIDA[0]=IDS_CONFIRM_CANCEL; @@ -4195,26 +4197,11 @@ int ClientConnection::HostDisconnectReturned(void *pParam,int iPad,C4JStorage::E ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&ClientConnection::ExitGameAndSaveReturned,nullptr); } else -#else - // Give the player the option to save their game - // does the save exist? - bool bSaveExists; - StorageManager.DoesSaveExist(&bSaveExists); - // 4J-PB - we check if the save exists inside the libs - // we need to ask if they are sure they want to overwrite the existing game - if(bSaveExists) { - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&ClientConnection::ExitGameAndSaveReturned,nullptr); - } - else -#endif - { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - StorageManager.SetSaveDisabled(false); -#endif + if(consoleAutosave) + { + StorageManager.SetSaveDisabled(false); + } MinecraftServer::getInstance()->setSaveOnExit( true ); // flag a app action of exit game app.SetAction(iPad,eAppAction_ExitWorld); diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp index c77746fa..890fd4c2 100644 --- a/Minecraft.Client/Common/Consoles_App.cpp +++ b/Minecraft.Client/Common/Consoles_App.cpp @@ -3253,11 +3253,17 @@ void CMinecraftApp::HandleXuiActions(void) app.SetAutosaveTimerTime(); SetAction(i,eAppAction_Idle); -#if defined(_XBOX_ONE) || defined(__ORBIS__) - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_AutoSaveGame); + const int controlType = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_ControlType); + const bool useAutosaveAnimation = (controlType == 0 || controlType == 1 || controlType == 4); - if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); -#else + if (useAutosaveAnimation) + { + new C4JThread(&UIScene_PauseMenu::SaveWorldThreadProc, (void*)true, "AutosaveSaveThread"); + if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); + ui.ShowSavingMessage(ProfileManager.GetPrimaryPad(), C4JStorage::ESavingMessage_Short); + } + else + { // turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen ui.HideAllGameUIElements(); @@ -3293,7 +3299,7 @@ void CMinecraftApp::HandleXuiActions(void) #endif ui.NavigateToScene(ProfileManager.GetPrimaryPad(),eUIScene_FullscreenProgress, loadingParams , eUILayer_Fullscreen, eUIGroup_Fullscreen); -#endif + } } break; case eAppAction_ExitPlayer: @@ -6398,7 +6404,6 @@ int CMinecraftApp::ExitAndJoinFromInvite(void *pParam,int iPad,C4JStorage::EMess return 0; } - int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) { CMinecraftApp *pClass = static_cast(pParam); @@ -6439,26 +6444,33 @@ int CMinecraftApp::ExitAndJoinFromInviteSaveDialogReturned(void *pParam,int iPad return S_OK; } } -#ifndef _XBOX_ONE - // does the save exist? - bool bSaveExists; - StorageManager.DoesSaveExist(&bSaveExists); - // 4J-PB - we check if the save exists inside the libs - // we need to ask if they are sure they want to overwrite the existing game - if(bSaveExists) + + const int controlType = app.GetGameSettings(iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); + + #ifndef _XBOX_ONE { - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); - return 0; + // does the save exist? + bool bSaveExists; + StorageManager.DoesSaveExist(&bSaveExists); + // 4J-PB - we check if the save exists inside the libs + // we need to ask if they are sure they want to overwrite the existing game + if(bSaveExists) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestErrorMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, ProfileManager.GetPrimaryPad(),&CMinecraftApp::ExitAndJoinFromInviteAndSaveReturned,pClass); + return 0; + } } - else -#endif + #endif + { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - StorageManager.SetSaveDisabled(false); -#endif + if(consoleAutosave) + { + StorageManager.SetSaveDisabled(false); + } MinecraftServer::getInstance()->setSaveOnExit( true ); } } @@ -7985,14 +7997,18 @@ void CMinecraftApp::EnterSaveNotificationSection() { if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save { - MinecraftServer::getInstance()->broadcastStartSavingPacket(); + MinecraftServer::getInstance()->broadcastStartSavingPacket(); - if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) - { - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); + const int controlType = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); + const bool isAutosaveAction = (app.GetXuiServerAction(ProfileManager.GetPrimaryPad()) == eXuiServerAction_AutoSaveGame); + const bool shouldPauseServer = g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 && !(consoleAutosave && isAutosaveAction); + if(shouldPauseServer) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); + } } } - } LeaveCriticalSection(&m_saveNotificationCriticalSection); } @@ -8003,14 +8019,18 @@ void CMinecraftApp::LeaveSaveNotificationSection() { if(g_NetworkManager.IsInSession()) // this can be triggered from the front end if we're downloading a save { - MinecraftServer::getInstance()->broadcastStopSavingPacket(); + MinecraftServer::getInstance()->broadcastStopSavingPacket(); - if( g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 ) - { - app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + const int controlType = app.GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); + const bool isAutosaveAction = (app.GetXuiServerAction(ProfileManager.GetPrimaryPad()) == eXuiServerAction_AutoSaveGame); + const bool shouldPauseServer = g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1 && !(consoleAutosave && isAutosaveAction); + if(shouldPauseServer) + { + app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)FALSE); + } } } - } LeaveCriticalSection(&m_saveNotificationCriticalSection); } @@ -8057,6 +8077,14 @@ int CMinecraftApp::RemoteSaveThreadProc( void* lpParameter ) return S_OK; } +UINT CMinecraftApp::GetCorrectExitKey(int iPad) +{ + const int controlType = GetGameSettings(iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); + + return consoleAutosave ? IDS_CONFIRM_EXIT_GAME_AUTOSAVE : IDS_CONFIRM_EXIT_GAME; +} + void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) { int primaryPad = ProfileManager.GetPrimaryPad(); @@ -8065,7 +8093,7 @@ void CMinecraftApp::ExitGameFromRemoteSave( LPVOID lpParameter ) uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,nullptr); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(primaryPad), uiIDA, 2, primaryPad,&CMinecraftApp::ExitGameFromRemoteSaveDialogReturned,nullptr); } int CMinecraftApp::ExitGameFromRemoteSaveDialogReturned(void *pParam,int iPad,C4JStorage::EMessageResult result) @@ -10184,11 +10212,13 @@ int CMinecraftApp::GetDLCInfoTexturesOffersCount() // AUTOSAVE void CMinecraftApp::SetAutosaveTimerTime(void) { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - m_uiAutosaveTimer= GetTickCount()+1000*60; -#else - m_uiAutosaveTimer= GetTickCount()+GetGameSettings(ProfileManager.GetPrimaryPad(),eGameSetting_Autosave)*1000*60*15; -#endif + int primaryPad = ProfileManager.GetPrimaryPad(); + const int controlType = app.GetGameSettings(primaryPad, eGameSetting_ControlType); + const bool fasterAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + if (fasterAutosave) + m_uiAutosaveTimer= GetTickCount() + GetGameSettings(primaryPad, eGameSetting_Autosave) * 1000 * 60; + else + m_uiAutosaveTimer= GetTickCount() + GetGameSettings(primaryPad, eGameSetting_Autosave) * 1000 * 60 * 15; }// value x 15 to get mins, x60 for secs bool CMinecraftApp::AutosaveDue(void) diff --git a/Minecraft.Client/Common/Consoles_App.h b/Minecraft.Client/Common/Consoles_App.h index 76ed2579..840a882b 100644 --- a/Minecraft.Client/Common/Consoles_App.h +++ b/Minecraft.Client/Common/Consoles_App.h @@ -675,6 +675,8 @@ public: // 4J Stu - Now storing the whole XUSER_SIGNIN_INFO so we can detect xuid changes XUSER_SIGNIN_INFO m_currentSigninInfo[XUSER_MAX_COUNT]; + UINT GetCorrectExitKey(int iPad); + //void OverrideFontRenderer(bool set, bool immediate = true); // void ToggleFontRenderer() { OverrideFontRenderer(!m_bFontRendererOverridden,false); } BANNEDLIST BannedListA[XUSER_MAX_COUNT]; diff --git a/Minecraft.Client/Common/UI/IUIScene_PauseMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_PauseMenu.cpp index fa10afc4..823bc895 100644 --- a/Minecraft.Client/Common/UI/IUIScene_PauseMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_PauseMenu.cpp @@ -27,6 +27,19 @@ int IUIScene_PauseMenu::ExitGameDialogReturned(void *pParam,int iPad,C4JStorage: // Results switched for this dialog if(result==C4JStorage::EMessage_ResultDecline) { + const int controlType = app.GetGameSettings(iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + const bool autosaveEnabled = consoleAutosave && !StorageManager.GetSaveDisabled() && (app.GetGameHostOption(eGameHostOption_DisableSaving) == 0); + + if(autosaveEnabled) + { + MinecraftServer::getInstance()->setSaveOnExit(true); + } + else + { + MinecraftServer::getInstance()->setSaveOnExit(false); + } + if(pScene) pScene->SetIgnoreInput(true); app.SetAction(iPad,eAppAction_ExitWorld); } @@ -159,7 +172,7 @@ int IUIScene_PauseMenu::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage } else { - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(), &IUIScene_PauseMenu::ExitGameSaveDialogReturned, pParam); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(ProfileManager.GetPrimaryPad()), uiIDA, 3, ProfileManager.GetPrimaryPad(), &IUIScene_PauseMenu::ExitGameSaveDialogReturned, pParam); } } } @@ -205,7 +218,7 @@ int IUIScene_PauseMenu::ExitGameDeclineSaveReturned(void *pParam,int iPad,C4JSto } else { - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, ProfileManager.GetPrimaryPad(),&IUIScene_PauseMenu::ExitGameSaveDialogReturned, pParam); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(ProfileManager.GetPrimaryPad()), uiIDA, 3, ProfileManager.GetPrimaryPad(),&IUIScene_PauseMenu::ExitGameSaveDialogReturned, pParam); } } @@ -373,14 +386,17 @@ int IUIScene_PauseMenu::SaveWorldThreadProc( LPVOID lpParameter ) if(ProfileManager.IsFullVersion()) { - app.SetGameStarted(false); + if(!bAutosave) + { + app.SetGameStarted(false); + } while( app.GetXuiServerAction(ProfileManager.GetPrimaryPad() ) != eXuiServerAction_Idle && !MinecraftServer::serverHalted() ) { Sleep(10); } - if(!MinecraftServer::serverHalted() && !app.GetChangingSessionType() ) app.SetGameStarted(true); + if(!bAutosave && !MinecraftServer::serverHalted() && !app.GetChangingSessionType() ) app.SetGameStarted(true); #if defined(_XBOX_ONE) || defined(__ORBIS__) if(app.GetGameHostOption(eGameHostOption_DisableSaving)) StorageManager.SetSaveDisabled(true); @@ -734,15 +750,19 @@ int IUIScene_PauseMenu::SaveGameDialogReturned(void *pParam,int iPad,C4JStorage: // results switched for this dialog if(result==C4JStorage::EMessage_ResultDecline) { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_TITLE_ENABLE_AUTOSAVE, IDS_CONFIRM_ENABLE_AUTOSAVE, uiIDA, 2, iPad,&IUIScene_PauseMenu::EnableAutosaveDialogReturned,pParam); -#else - // flag a app action of save game - app.SetAction(iPad,eAppAction_SaveGame); -#endif + const int controlType = app.GetGameSettings(iPad, eGameSetting_ControlType); + if (controlType == 0 || controlType == 1 || controlType == 4) // windows, xbox one, and ps4 + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestAlertMessage(IDS_TITLE_ENABLE_AUTOSAVE, IDS_CONFIRM_ENABLE_AUTOSAVE, uiIDA, 2, iPad,&IUIScene_PauseMenu::EnableAutosaveDialogReturned,pParam); + } + else + { + // flag a app action of save game + app.SetAction(iPad,eAppAction_SaveGame); + } } return 0; } diff --git a/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.cpp b/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.cpp index 9580789f..580ca81f 100644 --- a/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.cpp +++ b/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.cpp @@ -11,6 +11,7 @@ UIComponent_PressStartToPlay::UIComponent_PressStartToPlay(int iPad, void *initD m_showingSaveIcon = false; m_showingAutosaveTimer = false; m_showingTrialTimer = false; + m_saveIconPositionAdjusted = false; for(unsigned int i = 0; i < XUSER_MAX_COUNT; ++i) { m_showingPressStart[i] = false; @@ -43,6 +44,12 @@ wstring UIComponent_PressStartToPlay::getMoviePath() void UIComponent_PressStartToPlay::handleReload() { // 4J Stu - It's possible these could change during the reload, so can't use the normal controls refresh of it's state + if(!m_saveIconPositionAdjusted) + { + m_controlSaveIcon.setXPos(m_controlSaveIcon.getXPos() + 40); + m_controlSaveIcon.setYPos(m_controlSaveIcon.getYPos() - 70); + m_saveIconPositionAdjusted = true; + } m_controlSaveIcon.setVisible(m_showingSaveIcon); m_labelTrialTimer.setVisible(m_showingAutosaveTimer); m_labelTrialTimer.setLabel(m_autosaveTimer); @@ -126,6 +133,13 @@ void UIComponent_PressStartToPlay::handleTimerComplete(int id) ui.toastOn = false; } } + + if (id == 2) + { + showSaveIcon(false); + killTimer(id); + } + ui.ClearPressStart(); } @@ -197,6 +211,16 @@ void UIComponent_PressStartToPlay::showSaveIcon(bool show) { if(show) app.DebugPrintf("Tried to show save icon while texture pack reload was in progress\n"); } + + if(show) + { + killTimer(2); + addTimer(2, 1000); + } + else + { + killTimer(2); + } } void UIComponent_PressStartToPlay::showPlayerDisplayName(bool show) diff --git a/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.h b/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.h index 26a77cd7..aae30896 100644 --- a/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.h +++ b/Minecraft.Client/Common/UI/UIComponent_PressStartToPlay.h @@ -8,6 +8,7 @@ private: bool m_showingSaveIcon; bool m_showingAutosaveTimer; bool m_showingTrialTimer; + bool m_saveIconPositionAdjusted; bool m_showingPressStart[XUSER_MAX_COUNT]; wstring m_trialTimer; wstring m_autosaveTimer; diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 865519ba..49e92464 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -3150,11 +3150,15 @@ void UIController::ShowAutosaveCountdownTimer(bool show) void UIController::UpdateAutosaveCountdownTimer(unsigned int uiSeconds) { -#if !(defined(_XBOX_ONE) || defined(__ORBIS__)) - WCHAR wcAutosaveCountdown[100]; - swprintf( wcAutosaveCountdown, 100, app.GetString(IDS_AUTOSAVE_COUNTDOWN),uiSeconds); - if(m_groups[static_cast(eUIGroup_Fullscreen)]->getPressStartToPlay()) m_groups[static_cast(eUIGroup_Fullscreen)]->getPressStartToPlay()->setTrialTimer(wcAutosaveCountdown); -#endif + const int primaryPad = ProfileManager.GetPrimaryPad(); + const int controlType = app.GetGameSettings(primaryPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); + if (!consoleAutosave) + { + WCHAR wcAutosaveCountdown[100]; + swprintf( wcAutosaveCountdown, 100, app.GetString(IDS_AUTOSAVE_COUNTDOWN),uiSeconds); + if(m_groups[static_cast(eUIGroup_Fullscreen)]->getPressStartToPlay()) m_groups[static_cast(eUIGroup_Fullscreen)]->getPressStartToPlay()->setTrialTimer(wcAutosaveCountdown); + } } void UIController::ShowSavingMessage(unsigned int iPad, C4JStorage::ESavingMessage eVal) diff --git a/Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp b/Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp index 6384f7d5..1613078f 100644 --- a/Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_DeathMenu.cpp @@ -148,23 +148,28 @@ void UIScene_DeathMenu::handlePress(F64 controlId, F64 childId) break; } -#if defined (_XBOX_ONE) || defined(__ORBIS__) + + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if (consoleAutosave) + { if(g_NetworkManager.IsHost() && StorageManager.GetSaveDisabled()) { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_EXIT_GAME_SAVE; uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, m_iPad,&IUIScene_PauseMenu::ExitGameSaveDialogReturned,(LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 3, m_iPad,&IUIScene_PauseMenu::ExitGameSaveDialogReturned,(LPVOID)GetCallbackUniqueId()); } else { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned,(LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned,(LPVOID)GetCallbackUniqueId()); } - -#else + } + else { if(StorageManager.GetSaveDisabled()) { uiIDA[0]=IDS_CONFIRM_CANCEL; @@ -179,17 +184,17 @@ void UIScene_DeathMenu::handlePress(F64 controlId, F64 childId) uiIDA[1]=IDS_EXIT_GAME_SAVE; uiIDA[2]=IDS_EXIT_GAME_NO_SAVE; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, m_iPad,&IUIScene_PauseMenu::ExitGameSaveDialogReturned,(LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 3, m_iPad,&IUIScene_PauseMenu::ExitGameSaveDialogReturned,(LPVOID)GetCallbackUniqueId()); } else { uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned,(LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned,(LPVOID)GetCallbackUniqueId()); } } -#endif + } } else { diff --git a/Minecraft.Client/Common/UI/UIScene_PauseMenu.cpp b/Minecraft.Client/Common/UI/UIScene_PauseMenu.cpp index cf137320..34d6f407 100644 --- a/Minecraft.Client/Common/UI/UIScene_PauseMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_PauseMenu.cpp @@ -28,6 +28,9 @@ UIScene_PauseMenu::UIScene_PauseMenu(int iPad, void *initData, UILayer *parentLa // Setup all the Iggy references we need for this scene initialiseMovie(); m_bIgnoreInput=false; + m_savesDisabled=false; + m_bTrialTexturePack=false; + m_bErrorDialogRunning=false; m_eAction=eAction_None; m_buttons[BUTTON_PAUSE_RESUMEGAME].init(app.GetString(IDS_RESUME_GAME),BUTTON_PAUSE_RESUMEGAME); @@ -52,27 +55,36 @@ UIScene_PauseMenu::UIScene_PauseMenu(int iPad, void *initData, UILayer *parentLa m_bTrialTexturePack = true; } } - - // 4J-TomK - check for all possible labels being fed into BUTTON_PAUSE_SAVEGAME (Bug 163775) - // this has to be done before button initialisation! - wchar_t saveButtonLabels[2][256]; - swprintf( saveButtonLabels[0], 256, L"%ls", app.GetString( IDS_SAVE_GAME )); - swprintf( saveButtonLabels[1], 256, L"%ls", app.GetString( IDS_DISABLE_AUTOSAVE )); - m_buttons[BUTTON_PAUSE_SAVEGAME].setAllPossibleLabels(2,saveButtonLabels); - - if(app.GetGameHostOption(eGameHostOption_DisableSaving) || m_bTrialTexturePack) - { - m_savesDisabled = true; - m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_SAVE_GAME),BUTTON_PAUSE_SAVEGAME); - } - else - { - m_savesDisabled = false; - m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_DISABLE_AUTOSAVE),BUTTON_PAUSE_SAVEGAME); - } -#else - m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_SAVE_GAME),BUTTON_PAUSE_SAVEGAME); #endif + + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if (consoleAutosave) + { + // 4J-TomK - check for all possible labels being fed into BUTTON_PAUSE_SAVEGAME (Bug 163775) + // this has to be done before button initialisation! + wchar_t saveButtonLabels[2][256]; + swprintf( saveButtonLabels[0], 256, L"%ls", app.GetString( IDS_SAVE_GAME )); + swprintf( saveButtonLabels[1], 256, L"%ls", app.GetString( IDS_DISABLE_AUTOSAVE )); + m_buttons[BUTTON_PAUSE_SAVEGAME].setAllPossibleLabels(2,saveButtonLabels); + + if(app.GetGameHostOption(eGameHostOption_DisableSaving) || m_bTrialTexturePack) + { + m_savesDisabled = true; + m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_SAVE_GAME),BUTTON_PAUSE_SAVEGAME); + } + else + { + m_savesDisabled = false; + m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_DISABLE_AUTOSAVE),BUTTON_PAUSE_SAVEGAME); + } + } + else + { + m_buttons[BUTTON_PAUSE_SAVEGAME].init(app.GetString(IDS_SAVE_GAME),BUTTON_PAUSE_SAVEGAME); + } + m_buttons[BUTTON_PAUSE_EXITGAME].init(app.GetString(IDS_EXIT_GAME),BUTTON_PAUSE_EXITGAME); if(!ProfileManager.IsFullVersion()) @@ -143,41 +155,46 @@ void UIScene_PauseMenu::tick() { UIScene::tick(); -#ifdef __PSVITA__ - // 4J-MGH - Need to check for installed DLC here, as we delay the installation of the key file on Vita - if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(0); -#endif + #ifdef __PSVITA__ + // 4J-MGH - Need to check for installed DLC here, as we delay the installation of the key file on Vita + if(!app.DLCInstallProcessCompleted()) app.StartInstallDLCProcess(0); + #endif + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 -#if defined _XBOX_ONE || defined __ORBIS__ - if(!m_bTrialTexturePack && m_savesDisabled != (app.GetGameHostOption(eGameHostOption_DisableSaving) != 0) && ProfileManager.GetPrimaryPad() == m_iPad ) + if (consoleAutosave) { - // We show the save button if saves are disabled as this lets us show a prompt to enable them (via purchasing a texture pack) - if( app.GetGameHostOption(eGameHostOption_DisableSaving) ) + if(!m_bTrialTexturePack && m_savesDisabled != (app.GetGameHostOption(eGameHostOption_DisableSaving) != 0) && ProfileManager.GetPrimaryPad() == m_iPad ) { - m_savesDisabled = true; - m_buttons[BUTTON_PAUSE_SAVEGAME].setLabel( app.GetString(IDS_SAVE_GAME) ); - } - else - { - m_savesDisabled = false; - m_buttons[BUTTON_PAUSE_SAVEGAME].setLabel( app.GetString(IDS_DISABLE_AUTOSAVE) ); + // We show the save button if saves are disabled as this lets us show a prompt to enable them (via purchasing a texture pack) + if( app.GetGameHostOption(eGameHostOption_DisableSaving) ) + { + m_savesDisabled = true; + printf("PauseMenu::tick: setLabel IDS_SAVE_GAME (%ls)\n", app.GetString(IDS_SAVE_GAME)); + m_buttons[BUTTON_PAUSE_SAVEGAME].setLabel( app.GetString(IDS_SAVE_GAME) ); + } + else + { + m_savesDisabled = false; + printf("PauseMenu::tick: setLabel IDS_DISABLE_AUTOSAVE (%ls)\n", app.GetString(IDS_DISABLE_AUTOSAVE)); + m_buttons[BUTTON_PAUSE_SAVEGAME].setLabel( app.GetString(IDS_DISABLE_AUTOSAVE) ); + } } } -#endif -#ifdef __ORBIS__ - // Process the error dialog (for a patch being available) - if(m_bErrorDialogRunning) - { - SceErrorDialogStatus stat = sceErrorDialogUpdateStatus(); - if( stat == SCE_ERROR_DIALOG_STATUS_FINISHED ) - { - sceErrorDialogTerminate(); - m_bErrorDialogRunning=false; + #ifdef __ORBIS__ + // Process the error dialog (for a patch being available) + if(m_bErrorDialogRunning) + { + SceErrorDialogStatus stat = sceErrorDialogUpdateStatus(); + if( stat == SCE_ERROR_DIALOG_STATUS_FINISHED ) + { + sceErrorDialogTerminate(); + m_bErrorDialogRunning=false; + } } - } -#endif + #endif } void UIScene_PauseMenu::updateTooltips() @@ -239,8 +256,9 @@ void UIScene_PauseMenu::updateComponents() void UIScene_PauseMenu::handlePreReload() { -#if defined _XBOX_ONE || defined __ORBIS__ - if(ProfileManager.GetPrimaryPad() == m_iPad) + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + if(consoleAutosave && (ProfileManager.GetPrimaryPad() == m_iPad)) { // 4J-TomK - check for all possible labels being fed into BUTTON_PAUSE_SAVEGAME (Bug 163775) // this has to be done before button initialisation! @@ -249,7 +267,6 @@ void UIScene_PauseMenu::handlePreReload() swprintf( saveButtonLabels[1], 256, L"%ls", app.GetString( IDS_DISABLE_AUTOSAVE )); m_buttons[BUTTON_PAUSE_SAVEGAME].setAllPossibleLabels(2,saveButtonLabels); } -#endif } void UIScene_PauseMenu::handleReload() @@ -257,8 +274,10 @@ void UIScene_PauseMenu::handleReload() updateTooltips(); updateControlsVisibility(); -#if defined _XBOX_ONE || defined __ORBIS__ - if(ProfileManager.GetPrimaryPad() == m_iPad) + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if(consoleAutosave && ProfileManager.GetPrimaryPad() == m_iPad) { // We show the save button if saves are disabled as this lets us show a prompt to enable them (via purchasing a texture pack) if( app.GetGameHostOption(eGameHostOption_DisableSaving) || m_bTrialTexturePack ) @@ -272,7 +291,6 @@ void UIScene_PauseMenu::handleReload() m_buttons[BUTTON_PAUSE_SAVEGAME].setLabel( app.GetString(IDS_DISABLE_AUTOSAVE) ); } } -#endif doHorizontalResizeCheck(); } @@ -660,8 +678,12 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) playTime = static_cast(pMinecraft->localplayers[m_iPad]->getSessionTimer()); } -#if defined(_XBOX_ONE) || defined(__ORBIS__) - uiIDA[0]=IDS_CONFIRM_CANCEL; + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if (consoleAutosave) + { + uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; if(g_NetworkManager.IsHost() && StorageManager.GetSaveDisabled()) @@ -676,7 +698,7 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) } else { - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, m_iPad,&UIScene_PauseMenu::ExitGameSaveDialogReturned, (LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 3, m_iPad,&UIScene_PauseMenu::ExitGameSaveDialogReturned, (LPVOID)GetCallbackUniqueId()); } } else if(g_NetworkManager.IsHost() && g_NetworkManager.GetPlayerCount()>1) @@ -685,9 +707,11 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) } else { - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned, (LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned, (LPVOID)GetCallbackUniqueId()); } -#else + } + else + { if(StorageManager.GetSaveDisabled()) { uiIDA[0]=IDS_CONFIRM_CANCEL; @@ -708,7 +732,7 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) } else { - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, m_iPad,&UIScene_PauseMenu::ExitGameSaveDialogReturned, (LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 3, m_iPad,&UIScene_PauseMenu::ExitGameSaveDialogReturned, (LPVOID)GetCallbackUniqueId()); } } else @@ -716,10 +740,10 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) uiIDA[0]=IDS_CONFIRM_CANCEL; uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned, (LPVOID)GetCallbackUniqueId()); + ui.RequestAlertMessage(IDS_EXIT_GAME, app.GetCorrectExitKey(m_iPad), uiIDA, 2, m_iPad,&IUIScene_PauseMenu::ExitGameDialogReturned, (LPVOID)GetCallbackUniqueId()); } } -#endif + } } else { @@ -894,8 +918,10 @@ void UIScene_PauseMenu::PerformActionSaveGame() else #endif { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - if(!m_savesDisabled) + const int controlType = app.GetGameSettings(m_iPad, eGameSetting_ControlType); + const bool consoleAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if(consoleAutosave && !m_savesDisabled) { UINT uiIDA[2]; uiIDA[0]=IDS_CANCEL; @@ -903,7 +929,6 @@ void UIScene_PauseMenu::PerformActionSaveGame() ui.RequestAlertMessage(IDS_TITLE_DISABLE_AUTOSAVE, IDS_CONFIRM_DISABLE_AUTOSAVE, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::DisableAutosaveDialogReturned,(LPVOID)GetCallbackUniqueId()); } else -#endif // we need to ask if they are sure they want to overwrite the existing game if(bSaveExists) { @@ -914,15 +939,18 @@ void UIScene_PauseMenu::PerformActionSaveGame() } else { -#if defined(_XBOX_ONE) || defined(__ORBIS__) - UINT uiIDA[2]; - uiIDA[0]=IDS_CONFIRM_CANCEL; - uiIDA[1]=IDS_CONFIRM_OK; - ui.RequestAlertMessage(IDS_TITLE_ENABLE_AUTOSAVE, IDS_CONFIRM_ENABLE_AUTOSAVE, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::EnableAutosaveDialogReturned,(LPVOID)GetCallbackUniqueId()); -#else - // flag a app action of save game - app.SetAction(m_iPad,eAppAction_SaveGame); -#endif + if(consoleAutosave) + { + UINT uiIDA[2]; + uiIDA[0]=IDS_CONFIRM_CANCEL; + uiIDA[1]=IDS_CONFIRM_OK; + ui.RequestAlertMessage(IDS_TITLE_ENABLE_AUTOSAVE, IDS_CONFIRM_ENABLE_AUTOSAVE, uiIDA, 2, m_iPad,&IUIScene_PauseMenu::EnableAutosaveDialogReturned,(LPVOID)GetCallbackUniqueId()); + } + else + { + // flag a app action of save game + app.SetAction(m_iPad,eAppAction_SaveGame); + } } } } diff --git a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp index 42f057a8..97183a2d 100644 --- a/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp +++ b/Minecraft.Client/Common/UI/UIScene_SettingsOptionsMenu.cpp @@ -2,6 +2,25 @@ #include "UI.h" #include "UIScene_SettingsOptionsMenu.h" +namespace +{ + void FormatAutosaveSliderLabel(WCHAR *buffer, size_t bufferSize, int value, int controlType) + { + const bool fasterAutosave = (controlType == 0 || controlType == 1 || controlType == 4); // windows, xbox one and ps4 + + if(value == 0) + { + swprintf(buffer, bufferSize, L"%ls", app.GetString(IDS_SLIDER_AUTOSAVE_OFF)); + } + else + { + const int displayValue = fasterAutosave ? value : value * 15; + const wstring unitText = (displayValue == 1) ? L"Min" : app.GetString(IDS_MINUTES); + swprintf(buffer, bufferSize, L"%ls: %d %ls", app.GetString(IDS_SLIDER_AUTOSAVE), displayValue, unitText.c_str()); + } + } +} + int UIScene_SettingsOptionsMenu::m_iDifficultyTitleSettingA[4]= { IDS_DIFFICULTY_TITLE_PEACEFUL, @@ -74,10 +93,7 @@ void UIScene_SettingsOptionsMenu::tick() WCHAR TempString[256]; int autosaveVal = app.GetGameSettings(m_iPad,eGameSetting_Autosave); - if(autosaveVal == 0) - swprintf(TempString, 256, L"%ls", app.GetString(IDS_SLIDER_AUTOSAVE_OFF)); - else - swprintf(TempString, 256, L"%ls: %d %ls", app.GetString(IDS_SLIDER_AUTOSAVE), autosaveVal*15, app.GetString(IDS_MINUTES)); + FormatAutosaveSliderLabel(TempString, 256, autosaveVal, app.GetGameSettings(m_iPad, eGameSetting_ControlType)); m_multiList.AddNewSlider(TempString, eControl_Autosave, 0, 8, 1, autosaveVal); swprintf(TempString, 256, L"%ls: %d%%", app.GetString(IDS_SLIDER_SENSITIVITY_INGAME), app.GetGameSettings(m_iPad,eGameSetting_Sensitivity_InGame)); @@ -115,10 +131,7 @@ void UIScene_SettingsOptionsMenu::tick() case eControl_Autosave: app.SetGameSettings(m_iPad, eGameSetting_Autosave, m_iPendingSliderValue); app.SetAutosaveTimerTime(); - if(m_iPendingSliderValue == 0) - swprintf(TempString, 256, L"%ls", app.GetString(IDS_SLIDER_AUTOSAVE_OFF)); - else - swprintf(TempString, 256, L"%ls: %d %ls", app.GetString(IDS_SLIDER_AUTOSAVE), m_iPendingSliderValue*15, app.GetString(IDS_MINUTES)); + FormatAutosaveSliderLabel(TempString, 256, m_iPendingSliderValue, app.GetGameSettings(m_iPad, eGameSetting_ControlType)); m_multiList.SetSliderLabel(eControl_Autosave, TempString); break; case eControl_Sensitivity_InGame: diff --git a/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml b/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml index 4370b1fc..5a06756e 100644 --- a/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml +++ b/Minecraft.Client/Windows64Media/loc/stringsGeneric.xml @@ -5813,6 +5813,10 @@ Press{*CONTROLLER_VK_B*} if you already know about Fireworks. Are you sure you want to exit to the main menu? Any unsaved progress will be lost. + + Are you sure you want to exit to the main menu? + + Are you sure you want to exit to the main menu? Your progress will be lost! diff --git a/Minecraft.Client/Windows64Media/loc/stringsPlatformSpecific.xml b/Minecraft.Client/Windows64Media/loc/stringsPlatformSpecific.xml index d690dd11..f6b7a735 100644 --- a/Minecraft.Client/Windows64Media/loc/stringsPlatformSpecific.xml +++ b/Minecraft.Client/Windows64Media/loc/stringsPlatformSpecific.xml @@ -247,7 +247,21 @@ Please do not turn off your computer while this icon is on-screen. If you try to save while using the trial version, you will be given the option to purchase the full version. - + + Enable autosave + + + Would you like to enable the constant, automatic saving of the world? + + + Disable Autosave + + + Disable autosave + + + Are you sure you want to disable the constant, automatic saving of the world? + Small