#include "UI.h" #include "../../MinecraftServer.h" #include "../../MultiPlayerLocalPlayer.h" #pragma push_macro("byte") #pragma push_macro("GetNextSibling") #pragma push_macro("GetFirstChild") #undef byte #undef GetNextSibling #undef GetFirstChild #include "UIScene_PauseMenu.h" #include "RmlManager.h" #include "../../Windows64/KeyboardMouseInput.h" #include #include #pragma pop_macro("GetFirstChild") #pragma pop_macro("GetNextSibling") #pragma pop_macro("byte") UIScene_PauseMenu::UIScene_PauseMenu(int iPad, void *initData, UILayer *parentLayer) : UIScene_RmlBase(iPad, parentLayer) { Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx) { app.DebugPrintf("[RmlPauseMenu] No RmlUi context available\n"); return; } m_document = ctx->LoadDocument("PauseMenu.rml"); if (m_document) { app.DebugPrintf("[RmlPauseMenu] Document loaded OK, showing...\n"); m_document->Show(); app.DebugPrintf("[RmlPauseMenu] Document shown, visible=%d, context docs=%d\n", m_document->IsVisible(), ctx->GetNumDocuments()); RegisterEvents({ "resume", "help_options", "achievements", "save_game", "exit_game" }); m_document->GetElementById("resume")->Focus(); } else app.DebugPrintf("[RmlPauseMenu] Failed to load PauseMenu.rml\n"); ui.HidePressStart(); m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, false); m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, true); m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, true); if (g_NetworkManager.IsLocalGame() && g_NetworkManager.GetPlayerCount() == 1) app.SetXuiServerAction(ProfileManager.GetPrimaryPad(), eXuiServerAction_PauseServer, (void*)TRUE); TelemetryManager->RecordMenuShown(m_iPad, eUIScene_PauseMenu, 0); TelemetryManager->RecordPauseOrInactive(m_iPad); } UIScene_PauseMenu::~UIScene_PauseMenu() { if (m_document) { UnregisterEvents({ "resume", "help_options", "achievements", "save_game", "exit_game" }); m_document->Close(); } m_parentLayer->showComponent(m_iPad, eUIComponent_Panorama, false); m_parentLayer->showComponent(m_iPad, eUIComponent_MenuBackground, false); m_parentLayer->showComponent(m_iPad, eUIComponent_Logo, false); } void UIScene_PauseMenu::gainFocus() { if (!bHasFocus && stealsFocus()) { bHasFocus = true; updateTooltips(); updateComponents(); if (!m_bFocussedOnce) // No Iggy set-focus call needed for RmlUi scene handleGainFocus(m_bFocussedOnce); if (bHasFocus) m_bFocussedOnce = true; if (m_document) m_document->Show(); } } void UIScene_PauseMenu::handleLoseFocus() { if (m_document) m_document->Hide(); } void UIScene_PauseMenu::reloadMovie(bool force) { } //GabsPuN: When Iggy is completely replaced, some functions should be moved to UIScene.cpp. //This way, the tick() function won't be repeated in every UIScene_ cpp file. //Also, since iggy no longer exists, we can take liberties with optimization or code //that is easier to work with. void UIScene_PauseMenu::tick() { // Signal the base class that we've ticked once, so it sets m_bCanHandleInput // (the Iggy while-loop that normally sets this never runs without a loaded SWF) m_hasTickedOnce = true; UIScene::tick(); Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx || !bHasFocus) return; //GabsPuN: Once the above comment is made, we can do something like this to increase performance. /* int currentX = g_KBMInput.GetMouseX(); int currentY = g_KBMInput.GetMouseY(); if (currentX != m_lastMouseX || currentY != m_lastMouseY) { ctx->ProcessMouseMove(currentX, currentY, 0); m_lastMouseX = currentX; m_lastMouseY = currentY; } */ // Forward mouse position (for hover effects and correct click targeting) ctx->ProcessMouseMove(g_KBMInput.GetMouseX(), g_KBMInput.GetMouseY(), 0); // Forward mouse button presses/releases if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_LEFT)) ctx->ProcessMouseButtonDown(0, 0); if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_LEFT)) ctx->ProcessMouseButtonUp(0, 0); if (g_KBMInput.IsMouseButtonPressed(KeyboardMouseInput::MOUSE_RIGHT)) ctx->ProcessMouseButtonDown(1, 0); if (g_KBMInput.IsMouseButtonReleased(KeyboardMouseInput::MOUSE_RIGHT)) ctx->ProcessMouseButtonUp(1, 0); // Forward scroll wheel int wheelDelta = g_KBMInput.GetMouseWheel(); if (wheelDelta != 0) ctx->ProcessMouseWheel(wheelDelta / -120, 0); ctx->Update(); } void UIScene_PauseMenu::render(S32 width, S32 height, C4JRender::eViewportType viewport) { } void UIScene_PauseMenu::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled) { if (m_bIgnoreInput) return; if (pressed) { if (iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame()) app.SetXuiServerAction(ProfileManager.GetPrimaryPad(), eXuiServerAction_PauseServer, (void*)FALSE); } Rml::Context* ctx = RmlManager::Get().GetContext(); if (!ctx) return; if (!pressed) return; switch (key) { case ACTION_MENU_UP: ctx->ProcessKeyDown(Rml::Input::KI_UP, 0); handled = true; break; case ACTION_MENU_DOWN: ctx->ProcessKeyDown(Rml::Input::KI_DOWN, 0); handled = true; break; case ACTION_MENU_OK: if (g_KBMInput.IsKeyPressed(VK_RETURN)) { ctx->ProcessKeyDown(Rml::Input::KI_RETURN, 0); handled = true; } break; case ACTION_MENU_CANCEL: case ACTION_MENU_PAUSEMENU: navigateBack(); handled = true; break; default: break; } } void UIScene_PauseMenu::ProcessEvent(Rml::Event& event) { if (m_bIgnoreInput) return; const Rml::String& id = event.GetCurrentElement()->GetId(); if (event == Rml::EventId::Click) { if (id == "resume") OnResume(); else if (id == "help_options") OnHelpAndOptions(); else if (id == "achievements") OnAchievements(); else if (id == "save_game") OnSaveGame(); else if (id == "exit_game") OnExitGame(); } } void UIScene_PauseMenu::ShowScene(bool show) { if (m_document) { if (show) m_document->Show(); else m_document->Hide(); } } void UIScene_PauseMenu::navigateBack() { if (m_iPad == ProfileManager.GetPrimaryPad() && g_NetworkManager.IsLocalGame()) app.SetXuiServerAction(ProfileManager.GetPrimaryPad(), eXuiServerAction_PauseServer, (void*)FALSE); ui.PlayUISFX(eSFX_Back); UIScene::navigateBack(); } void UIScene_PauseMenu::OnResume() { ui.PlayUISFX(eSFX_Back); navigateBack(); } void UIScene_PauseMenu::OnHelpAndOptions() { ui.NavigateToScene(m_iPad, eUIScene_HelpAndOptionsMenu); } void UIScene_PauseMenu::OnAchievements() { ui.NavigateToScene(m_iPad, eUIScene_AchievementsMenu); } void UIScene_PauseMenu::OnSaveGame() { if (m_iPad != ProfileManager.GetPrimaryPad()) return; bool bSaveExists; StorageManager.DoesSaveExist(&bSaveExists); if (bSaveExists) { UINT uiIDA[2]; uiIDA[0] = IDS_CONFIRM_CANCEL; uiIDA[1] = IDS_CONFIRM_OK; ui.RequestAlertMessage(IDS_TITLE_SAVE_GAME, IDS_CONFIRM_SAVE_GAME, uiIDA, 2, m_iPad, &IUIScene_PauseMenu::SaveGameDialogReturned, (LPVOID)GetCallbackUniqueId()); } else { app.SetAction(m_iPad, eAppAction_SaveGame); } } void UIScene_PauseMenu::OnExitGame() { Minecraft* pMinecraft = Minecraft::GetInstance(); UINT uiIDA[3]; if (m_iPad == ProfileManager.GetPrimaryPad()) { int playTime = -1; if (pMinecraft->localplayers[m_iPad] != NULL) playTime = (int)pMinecraft->localplayers[m_iPad]->getSessionTimer(); if (StorageManager.GetSaveDisabled()) { uiIDA[0] = IDS_CONFIRM_CANCEL; uiIDA[1] = IDS_CONFIRM_OK; ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_PROGRESS_LOST, uiIDA, 2, m_iPad, &IUIScene_PauseMenu::ExitGameDialogReturned, (LPVOID)GetCallbackUniqueId()); } else { if (g_NetworkManager.IsHost()) { uiIDA[0] = IDS_CONFIRM_CANCEL; uiIDA[1] = IDS_EXIT_GAME_SAVE; uiIDA[2] = IDS_EXIT_GAME_NO_SAVE; if (g_NetworkManager.GetPlayerCount() > 1) ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME_CONFIRM_DISCONNECT_SAVE, uiIDA, 3, m_iPad, &UIScene_PauseMenu::ExitGameSaveDialogReturned, (LPVOID)GetCallbackUniqueId()); else ui.RequestAlertMessage(IDS_EXIT_GAME, IDS_CONFIRM_EXIT_GAME, uiIDA, 3, m_iPad, &UIScene_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()); } } } else { int playTime = -1; if (pMinecraft->localplayers[m_iPad] != NULL) playTime = (int)pMinecraft->localplayers[m_iPad]->getSessionTimer(); if (pMinecraft->localplayers[m_iPad] != nullptr) TelemetryManager->RecordLevelExit(m_iPad, eSen_LevelExitStatus_Exited); app.SetAction(m_iPad, eAppAction_ExitPlayer); return; } }