mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-25 11:53:36 +00:00
i noticed that the exit game button on the menu screen wasn't working, so i went ahead and enabled it and added the behavior to close the game. i added a Close method in the 4J_Render class and made a tweak to the _xbox check. the catch is that it uses the xbox text for the confirmation button, so i’m not sure if it’s the best approach, but it does work fine for me Signed-off-by: ViniciusCruzMoura <contato.cruz.moura@gmail.com>
880 lines
22 KiB
C++
880 lines
22 KiB
C++
#include "../../Minecraft.World/Platform/stdafx.h"
|
|
#include "UI.h"
|
|
#include "UILayer.h"
|
|
#include "UIScene.h"
|
|
|
|
UILayer::UILayer(UIGroup *parent)
|
|
{
|
|
m_parentGroup = parent;
|
|
m_hasFocus = false;
|
|
m_bMenuDisplayed = false;
|
|
m_bPauseMenuDisplayed = false;
|
|
m_bContainerMenuDisplayed = false;
|
|
m_bIgnoreAutosaveMenuDisplayed = false;
|
|
m_bIgnorePlayerJoinMenuDisplayed = false;
|
|
}
|
|
|
|
void UILayer::tick()
|
|
{
|
|
// Delete old scenes - deleting a scene can cause a new scene to be deleted, so we need to make a copy of the scenes that we are going to try and destroy this tick
|
|
std::vector<UIScene *>scenesToDeleteCopy;
|
|
for( AUTO_VAR(it,m_scenesToDelete.begin()); it != m_scenesToDelete.end(); it++)
|
|
{
|
|
UIScene *scene = (*it);
|
|
scenesToDeleteCopy.push_back(scene);
|
|
}
|
|
m_scenesToDelete.clear();
|
|
|
|
// Delete the scenes in our copy if they are ready to delete, otherwise add back to the ones that are still to be deleted. Actually deleting a scene might also add something back into m_scenesToDelete.
|
|
for( AUTO_VAR(it,scenesToDeleteCopy.begin()); it != scenesToDeleteCopy.end(); it++)
|
|
{
|
|
UIScene *scene = (*it);
|
|
if( scene->isReadyToDelete())
|
|
{
|
|
delete scene;
|
|
}
|
|
else
|
|
{
|
|
m_scenesToDelete.push_back(scene);
|
|
}
|
|
}
|
|
|
|
while (!m_scenesToDestroy.empty())
|
|
{
|
|
UIScene *scene = m_scenesToDestroy.back();
|
|
m_scenesToDestroy.pop_back();
|
|
scene->destroyMovie();
|
|
}
|
|
m_scenesToDestroy.clear();
|
|
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
(*it)->tick();
|
|
}
|
|
// Note: reverse iterator, the last element is the top of the stack
|
|
int sceneIndex = m_sceneStack.size() - 1;
|
|
//for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
while( sceneIndex >= 0 && sceneIndex < m_sceneStack.size() )
|
|
{
|
|
//(*it)->tick();
|
|
UIScene *scene = m_sceneStack[sceneIndex];
|
|
scene->tick();
|
|
--sceneIndex;
|
|
// TODO: We may wish to ignore ticking the rest of the stack based on this scene
|
|
}
|
|
}
|
|
|
|
void UILayer::render(S32 width, S32 height, C4JRender::eViewportType viewport)
|
|
{
|
|
if(!ui.IsExpectingOrReloadingSkin())
|
|
{
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
AUTO_VAR(itRef,m_componentRefCount.find((*it)->getSceneType()));
|
|
if(itRef != m_componentRefCount.end() && itRef->second.second)
|
|
{
|
|
if((*it)->isVisible() )
|
|
{
|
|
PIXBeginNamedEvent(0, "Rendering component %d", (*it)->getSceneType() );
|
|
(*it)->render(width, height,viewport);
|
|
PIXEndNamedEvent();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(!m_sceneStack.empty())
|
|
{
|
|
int lowestRenderable = m_sceneStack.size() - 1;
|
|
for(;lowestRenderable >= 0; --lowestRenderable)
|
|
{
|
|
if(m_sceneStack[lowestRenderable]->hidesLowerScenes()) break;
|
|
}
|
|
if(lowestRenderable < 0) lowestRenderable = 0;
|
|
for(;lowestRenderable < m_sceneStack.size(); ++lowestRenderable)
|
|
{
|
|
if(m_sceneStack[lowestRenderable]->isVisible() && (!ui.IsExpectingOrReloadingSkin() || m_sceneStack[lowestRenderable]->getSceneType()==eUIScene_Timer))
|
|
{
|
|
PIXBeginNamedEvent(0, "Rendering scene %d", m_sceneStack[lowestRenderable]->getSceneType() );
|
|
m_sceneStack[lowestRenderable]->render(width, height,viewport);
|
|
PIXEndNamedEvent();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UILayer::IsSceneInStack(EUIScene scene)
|
|
{
|
|
bool inStack = false;
|
|
for(int i = m_sceneStack.size() - 1;i >= 0; --i)
|
|
{
|
|
if(m_sceneStack[i]->getSceneType() == scene)
|
|
{
|
|
inStack = true;
|
|
break;
|
|
}
|
|
}
|
|
return inStack;
|
|
}
|
|
|
|
bool UILayer::HasFocus(int iPad)
|
|
{
|
|
bool hasFocus = false;
|
|
if(m_hasFocus)
|
|
{
|
|
for(int i = m_sceneStack.size() - 1;i >= 0; --i)
|
|
{
|
|
if(m_sceneStack[i]->stealsFocus() )
|
|
{
|
|
if(m_sceneStack[i]->hasFocus(iPad))
|
|
{
|
|
hasFocus = true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return hasFocus;
|
|
}
|
|
|
|
bool UILayer::hidesLowerScenes()
|
|
{
|
|
bool hidesScenes = false;
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
if((*it)->hidesLowerScenes())
|
|
{
|
|
hidesScenes = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!hidesScenes && !m_sceneStack.empty())
|
|
{
|
|
for(int i = m_sceneStack.size() - 1;i >= 0; --i)
|
|
{
|
|
if(m_sceneStack[i]->hidesLowerScenes())
|
|
{
|
|
hidesScenes = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return hidesScenes;
|
|
}
|
|
|
|
void UILayer::getRenderDimensions(S32 &width, S32 &height)
|
|
{
|
|
m_parentGroup->getRenderDimensions(width, height);
|
|
}
|
|
|
|
void UILayer::DestroyAll()
|
|
{
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
(*it)->destroyMovie();
|
|
}
|
|
for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
|
|
{
|
|
(*it)->destroyMovie();
|
|
}
|
|
}
|
|
|
|
void UILayer::ReloadAll(bool force)
|
|
{
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
(*it)->reloadMovie(force);
|
|
}
|
|
if(!m_sceneStack.empty())
|
|
{
|
|
int lowestRenderable = 0;
|
|
for(;lowestRenderable < m_sceneStack.size(); ++lowestRenderable)
|
|
{
|
|
m_sceneStack[lowestRenderable]->reloadMovie();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool UILayer::GetMenuDisplayed()
|
|
{
|
|
return m_bMenuDisplayed;
|
|
}
|
|
|
|
bool UILayer::NavigateToScene(int iPad, EUIScene scene, void *initData)
|
|
{
|
|
UIScene *newScene = NULL;
|
|
switch(scene)
|
|
{
|
|
// Debug
|
|
#ifdef _DEBUG_MENUS_ENABLED
|
|
case eUIScene_DebugOverlay:
|
|
newScene = new UIScene_DebugOverlay(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DebugSetCamera:
|
|
newScene = new UIScene_DebugSetCamera(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DebugCreateSchematic:
|
|
newScene = new UIScene_DebugCreateSchematic(iPad, initData, this);
|
|
break;
|
|
#endif
|
|
case eUIScene_DebugOptions:
|
|
newScene = new UIScene_DebugOptionsMenu(iPad, initData, this);
|
|
break;
|
|
|
|
// Containers
|
|
case eUIScene_InventoryMenu:
|
|
newScene = new UIScene_InventoryMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_CreativeMenu:
|
|
newScene = new UIScene_CreativeMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_ContainerMenu:
|
|
case eUIScene_LargeContainerMenu:
|
|
newScene = new UIScene_ContainerMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_BrewingStandMenu:
|
|
newScene = new UIScene_BrewingStandMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DispenserMenu:
|
|
newScene = new UIScene_DispenserMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_EnchantingMenu:
|
|
newScene = new UIScene_EnchantingMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_FurnaceMenu:
|
|
newScene = new UIScene_FurnaceMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_Crafting2x2Menu:
|
|
case eUIScene_Crafting3x3Menu:
|
|
newScene = new UIScene_CraftingMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_TradingMenu:
|
|
newScene = new UIScene_TradingMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_AnvilMenu:
|
|
newScene = new UIScene_AnvilMenu(iPad, initData, this);
|
|
break;
|
|
|
|
// Help and Options
|
|
case eUIScene_HelpAndOptionsMenu:
|
|
newScene = new UIScene_HelpAndOptionsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsMenu:
|
|
newScene = new UIScene_SettingsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsOptionsMenu:
|
|
newScene = new UIScene_SettingsOptionsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsAudioMenu:
|
|
newScene = new UIScene_SettingsAudioMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsControlMenu:
|
|
newScene = new UIScene_SettingsControlMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsGraphicsMenu:
|
|
newScene = new UIScene_SettingsGraphicsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SettingsUIMenu:
|
|
newScene = new UIScene_SettingsUIMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SkinSelectMenu:
|
|
newScene = new UIScene_SkinSelectMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_HowToPlayMenu:
|
|
newScene = new UIScene_HowToPlayMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_HowToPlay:
|
|
newScene = new UIScene_HowToPlay(iPad, initData, this);
|
|
break;
|
|
case eUIScene_ControlsMenu:
|
|
newScene = new UIScene_ControlsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_ReinstallMenu:
|
|
newScene = new UIScene_ReinstallMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_Credits:
|
|
newScene = new UIScene_Credits(iPad, initData, this);
|
|
break;
|
|
|
|
|
|
// Other in-game
|
|
case eUIScene_PauseMenu:
|
|
newScene = new UIScene_PauseMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DeathMenu:
|
|
newScene = new UIScene_DeathMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_ConnectingProgress:
|
|
newScene = new UIScene_ConnectingProgress(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SignEntryMenu:
|
|
newScene = new UIScene_SignEntryMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_InGameInfoMenu:
|
|
newScene = new UIScene_InGameInfoMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_InGameHostOptionsMenu:
|
|
newScene = new UIScene_InGameHostOptionsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_InGamePlayerOptionsMenu:
|
|
newScene = new UIScene_InGamePlayerOptionsMenu(iPad, initData, this);
|
|
break;
|
|
#if defined(_XBOX_ONE) || defined(__ORBIS__)
|
|
case eUIScene_InGameSaveManagementMenu:
|
|
newScene = new UIScene_InGameSaveManagementMenu(iPad, initData, this);
|
|
break;
|
|
#endif
|
|
case eUIScene_TeleportMenu:
|
|
newScene = new UIScene_TeleportMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_EndPoem:
|
|
if(IsSceneInStack(eUIScene_EndPoem))
|
|
{
|
|
app.DebugPrintf("Skipped EndPoem as one was already showing\n");
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
newScene = new UIScene_EndPoem(iPad, initData, this);
|
|
}
|
|
break;
|
|
|
|
|
|
// Frontend
|
|
case eUIScene_TrialExitUpsell:
|
|
newScene = new UIScene_TrialExitUpsell(iPad, initData, this);
|
|
app.DebugPrintf("UILayer::NavigateToScene AFTER UIScene_TrialExitUpsell CALL\n");
|
|
break;
|
|
case eUIScene_Intro:
|
|
newScene = new UIScene_Intro(iPad, initData, this);
|
|
break;
|
|
case eUIScene_SaveMessage:
|
|
newScene = new UIScene_SaveMessage(iPad, initData, this);
|
|
break;
|
|
case eUIScene_MainMenu:
|
|
newScene = new UIScene_MainMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_LoadOrJoinMenu:
|
|
newScene = new UIScene_LoadOrJoinMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_LoadMenu:
|
|
newScene = new UIScene_LoadMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_JoinMenu:
|
|
newScene = new UIScene_JoinMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_CreateWorldMenu:
|
|
newScene = new UIScene_CreateWorldMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_LaunchMoreOptionsMenu:
|
|
newScene = new UIScene_LaunchMoreOptionsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_FullscreenProgress:
|
|
newScene = new UIScene_FullscreenProgress(iPad, initData, this);
|
|
break;
|
|
case eUIScene_LeaderboardsMenu:
|
|
newScene = new UIScene_LeaderboardsMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DLCMainMenu:
|
|
newScene = new UIScene_DLCMainMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_DLCOffersMenu:
|
|
newScene = new UIScene_DLCOffersMenu(iPad, initData, this);
|
|
break;
|
|
case eUIScene_EULA:
|
|
newScene = new UIScene_EULA(iPad, initData, this);
|
|
break;
|
|
|
|
// Other
|
|
case eUIScene_Keyboard:
|
|
newScene = new UIScene_Keyboard(iPad, initData, this);
|
|
break;
|
|
case eUIScene_QuadrantSignin:
|
|
newScene = new UIScene_QuadrantSignin(iPad, initData, this);
|
|
break;
|
|
case eUIScene_MessageBox:
|
|
if(IsSceneInStack(eUIScene_MessageBox))
|
|
{
|
|
app.DebugPrintf("Skipped MessageBox as one was already showing\n");
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
newScene = new UIScene_MessageBox(iPad, initData, this);
|
|
}
|
|
break;
|
|
case eUIScene_Timer:
|
|
newScene = new UIScene_Timer(iPad, initData, this);
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
|
|
if(newScene == NULL)
|
|
{
|
|
app.DebugPrintf("WARNING: Scene %d was not created. Add it to UILayer::NavigateToScene\n", scene);
|
|
return false;
|
|
}
|
|
|
|
if(m_sceneStack.size() > 0)
|
|
{
|
|
newScene->setBackScene(m_sceneStack[m_sceneStack.size()-1]);
|
|
}
|
|
|
|
m_sceneStack.push_back(newScene);
|
|
|
|
updateFocusState();
|
|
|
|
newScene->tick();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool UILayer::NavigateBack(int iPad, EUIScene eScene)
|
|
{
|
|
if(m_sceneStack.size() == 0) return false;
|
|
|
|
bool navigated = false;
|
|
if(eScene < eUIScene_COUNT)
|
|
{
|
|
UIScene *scene = NULL;
|
|
do
|
|
{
|
|
scene = m_sceneStack.back();
|
|
if(scene->getSceneType() == eScene)
|
|
{
|
|
navigated = true;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if(scene->hasFocus(iPad))
|
|
{
|
|
removeScene(scene);
|
|
}
|
|
else
|
|
{
|
|
// No focus on the top scene, so this use shouldn't be navigating!
|
|
break;
|
|
}
|
|
}
|
|
} while(m_sceneStack.size() > 0);
|
|
|
|
}
|
|
else
|
|
{
|
|
UIScene *scene = m_sceneStack.back();
|
|
if(scene->hasFocus(iPad))
|
|
{
|
|
removeScene(scene);
|
|
navigated = true;
|
|
}
|
|
}
|
|
return navigated;
|
|
}
|
|
|
|
void UILayer::showComponent(int iPad, EUIScene scene, bool show)
|
|
{
|
|
AUTO_VAR(it,m_componentRefCount.find(scene));
|
|
if(it != m_componentRefCount.end())
|
|
{
|
|
it->second.second = show;
|
|
return;
|
|
}
|
|
if(show) addComponent(iPad,scene);
|
|
}
|
|
|
|
bool UILayer::isComponentVisible(EUIScene scene)
|
|
{
|
|
bool visible = false;
|
|
AUTO_VAR(it,m_componentRefCount.find(scene));
|
|
if(it != m_componentRefCount.end())
|
|
{
|
|
visible = it->second.second;
|
|
}
|
|
return visible;
|
|
}
|
|
|
|
UIScene *UILayer::addComponent(int iPad, EUIScene scene, void *initData)
|
|
{
|
|
AUTO_VAR(it,m_componentRefCount.find(scene));
|
|
if(it != m_componentRefCount.end())
|
|
{
|
|
++it->second.first;
|
|
|
|
for(AUTO_VAR(itComp,m_components.begin()); itComp != m_components.end(); ++itComp)
|
|
{
|
|
if( (*itComp)->getSceneType() == scene )
|
|
{
|
|
return *itComp;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
UIScene *newScene = NULL;
|
|
|
|
switch(scene)
|
|
{
|
|
case eUIComponent_Panorama:
|
|
newScene = new UIComponent_Panorama(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_DebugUIConsole:
|
|
newScene = new UIComponent_DebugUIConsole(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_DebugUIMarketingGuide:
|
|
newScene = new UIComponent_DebugUIMarketingGuide(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_Logo:
|
|
newScene = new UIComponent_Logo(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_Tooltips:
|
|
newScene = new UIComponent_Tooltips(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_TutorialPopup:
|
|
newScene = new UIComponent_TutorialPopup(iPad, initData, this);
|
|
// Start hidden
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,false);
|
|
break;
|
|
case eUIScene_HUD:
|
|
newScene = new UIScene_HUD(iPad, initData, this);
|
|
// Start hidden
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,false);
|
|
break;
|
|
case eUIComponent_Chat:
|
|
newScene = new UIComponent_Chat(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_PressStartToPlay:
|
|
newScene = new UIComponent_PressStartToPlay(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
case eUIComponent_MenuBackground:
|
|
newScene = new UIComponent_MenuBackground(iPad, initData, this);
|
|
m_componentRefCount[scene] = std::pair<int,bool>(1,true);
|
|
break;
|
|
default:
|
|
break;
|
|
};
|
|
|
|
if(newScene == NULL) return NULL;
|
|
|
|
m_components.push_back(newScene);
|
|
|
|
return newScene;
|
|
}
|
|
|
|
void UILayer::removeComponent(EUIScene scene)
|
|
{
|
|
AUTO_VAR(it,m_componentRefCount.find(scene));
|
|
if(it != m_componentRefCount.end())
|
|
{
|
|
--it->second.first;
|
|
|
|
if(it->second.first <= 0)
|
|
{
|
|
m_componentRefCount.erase(it);
|
|
for(AUTO_VAR(compIt, m_components.begin()) ; compIt != m_components.end(); )
|
|
{
|
|
if( (*compIt)->getSceneType() == scene)
|
|
{
|
|
#ifdef __PSVITA__
|
|
// remove any touchboxes
|
|
ui.TouchBoxesClear((*compIt));
|
|
#endif
|
|
m_scenesToDelete.push_back((*compIt));
|
|
(*compIt)->handleDestroy(); // For anything that might require the pointer be valid
|
|
compIt = m_components.erase(compIt);
|
|
}
|
|
else
|
|
{
|
|
++compIt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UILayer::removeScene(UIScene *scene)
|
|
{
|
|
#ifdef __PSVITA__
|
|
// remove any touchboxes
|
|
ui.TouchBoxesClear(scene);
|
|
#endif
|
|
|
|
AUTO_VAR(newEnd, std::remove(m_sceneStack.begin(), m_sceneStack.end(), scene) );
|
|
m_sceneStack.erase(newEnd, m_sceneStack.end());
|
|
|
|
m_scenesToDelete.push_back(scene);
|
|
|
|
scene->handleDestroy(); // For anything that might require the pointer be valid
|
|
|
|
bool hadFocus = m_hasFocus;
|
|
updateFocusState();
|
|
|
|
// If this layer has focus, pass it on
|
|
if (m_hasFocus || hadFocus)
|
|
{
|
|
m_hasFocus = false;
|
|
m_parentGroup->UpdateFocusState();
|
|
}
|
|
}
|
|
|
|
void UILayer::closeAllScenes()
|
|
{
|
|
std::vector<UIScene *> temp;
|
|
temp.insert(temp.end(), m_sceneStack.begin(), m_sceneStack.end());
|
|
m_sceneStack.clear();
|
|
for(AUTO_VAR(it, temp.begin()); it != temp.end(); ++it)
|
|
{
|
|
#ifdef __PSVITA__
|
|
// remove any touchboxes
|
|
ui.TouchBoxesClear(*it);
|
|
#endif
|
|
m_scenesToDelete.push_back(*it);
|
|
(*it)->handleDestroy(); // For anything that might require the pointer be valid
|
|
}
|
|
|
|
updateFocusState();
|
|
|
|
// If this layer has focus, pass it on
|
|
if (m_hasFocus)
|
|
{
|
|
m_hasFocus = false;
|
|
m_parentGroup->UpdateFocusState();
|
|
}
|
|
}
|
|
|
|
// Get top scene on stack (or NULL if stack is empty)
|
|
UIScene *UILayer::GetTopScene()
|
|
{
|
|
if(m_sceneStack.size() == 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
else
|
|
{
|
|
return m_sceneStack[m_sceneStack.size()-1];
|
|
}
|
|
}
|
|
|
|
// Updates layer focus state if no error message is present (unless this is the error layer)
|
|
bool UILayer::updateFocusState(bool allowedFocus /* = false */)
|
|
{
|
|
// If haveFocus is false, request it
|
|
if (!allowedFocus)
|
|
{
|
|
// To update focus in this layer we need to request focus from group
|
|
// Focus will be denied if there's an upper layer that needs focus
|
|
allowedFocus = m_parentGroup->RequestFocus(this);
|
|
}
|
|
|
|
m_bMenuDisplayed = false;
|
|
m_bPauseMenuDisplayed = false;
|
|
m_bContainerMenuDisplayed = false;
|
|
m_bIgnoreAutosaveMenuDisplayed = false;
|
|
m_bIgnorePlayerJoinMenuDisplayed = false;
|
|
|
|
bool layerFocusSet = false;
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *scene = *it;
|
|
|
|
// UPDATE FOCUS STATES
|
|
if(!layerFocusSet && allowedFocus && scene->stealsFocus())
|
|
{
|
|
scene->gainFocus();
|
|
layerFocusSet = true;
|
|
}
|
|
else
|
|
{
|
|
scene->loseFocus();
|
|
if(allowedFocus && app.GetGameStarted())
|
|
{
|
|
// 4J Stu - This is a memory optimisation so we don't keep scenes loaded in memory all the time
|
|
// This is required for PS3 (and likely Vita), but I'm removing it on XboxOne so that we can avoid
|
|
// the scene creation time (which can be >0.5s) since we have the memory to spare
|
|
#ifndef _XBOX_ONE
|
|
m_scenesToDestroy.push_back(scene);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/// UPDATE STACK STATES
|
|
|
|
// 4J-PB - this should just be true
|
|
m_bMenuDisplayed=true;
|
|
|
|
EUIScene sceneType = scene->getSceneType();
|
|
switch(sceneType)
|
|
{
|
|
case eUIScene_PauseMenu:
|
|
m_bPauseMenuDisplayed = true;
|
|
break;
|
|
case eUIScene_Crafting2x2Menu:
|
|
case eUIScene_Crafting3x3Menu:
|
|
case eUIScene_FurnaceMenu:
|
|
case eUIScene_ContainerMenu:
|
|
case eUIScene_LargeContainerMenu:
|
|
case eUIScene_InventoryMenu:
|
|
case eUIScene_CreativeMenu:
|
|
case eUIScene_DispenserMenu:
|
|
case eUIScene_BrewingStandMenu:
|
|
case eUIScene_EnchantingMenu:
|
|
m_bContainerMenuDisplayed=true;
|
|
|
|
// Intentional fall-through
|
|
case eUIScene_DeathMenu:
|
|
case eUIScene_FullscreenProgress:
|
|
case eUIScene_SignEntryMenu:
|
|
case eUIScene_EndPoem:
|
|
m_bIgnoreAutosaveMenuDisplayed = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch(sceneType)
|
|
{
|
|
case eUIScene_FullscreenProgress:
|
|
case eUIScene_EndPoem:
|
|
case eUIScene_Credits:
|
|
case eUIScene_LeaderboardsMenu:
|
|
m_bIgnorePlayerJoinMenuDisplayed = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
m_hasFocus = layerFocusSet;
|
|
|
|
return m_hasFocus;
|
|
}
|
|
|
|
#ifdef __PSVITA__
|
|
UIScene *UILayer::getCurrentScene()
|
|
{
|
|
// Note: reverse iterator, the last element is the top of the stack
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *scene = *it;
|
|
// 4J-PB - only used on Vita, so iPad 0 is fine
|
|
if(scene->hasFocus(0) && scene->canHandleInput())
|
|
{
|
|
return scene;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
void UILayer::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
|
|
{
|
|
// Note: reverse iterator, the last element is the top of the stack
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *scene = *it;
|
|
if(scene->hasFocus(iPad) && scene->canHandleInput())
|
|
{
|
|
// 4J-PB - ignore repeats of action ABXY buttons
|
|
// fix for PS3 213 - [MAIN MENU] Holding down buttons will continue to activate every prompt.
|
|
// 4J Stu - Changed this slightly to add the allowRepeat function so we can allow repeats in the crafting menu
|
|
if(repeat && !scene->allowRepeat(key) )
|
|
{
|
|
return;
|
|
}
|
|
scene->handleInput(iPad, key, repeat, pressed, released, handled);
|
|
}
|
|
|
|
// Fix for PS3 #444 - [IN GAME] If the user keeps pressing CROSS while on the 'Save Game' screen the title will crash.
|
|
handled = handled || scene->hidesLowerScenes();
|
|
if(handled ) break;
|
|
}
|
|
|
|
// Components can't take input or focus
|
|
}
|
|
|
|
void UILayer::HandleDLCMountingComplete()
|
|
{
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *topScene = *it;
|
|
app.DebugPrintf("UILayer::HandleDLCMountingComplete - topScene\n");
|
|
topScene->HandleDLCMountingComplete();
|
|
}
|
|
}
|
|
|
|
void UILayer::HandleDLCInstalled()
|
|
{
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *topScene = *it;
|
|
topScene->HandleDLCInstalled();
|
|
}
|
|
}
|
|
|
|
#ifdef _XBOX_ONE
|
|
void UILayer::HandleDLCLicenseChange()
|
|
{
|
|
for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
|
|
{
|
|
UIScene *topScene = *it;
|
|
topScene->HandleDLCLicenseChange();
|
|
}
|
|
}
|
|
#endif
|
|
|
|
bool UILayer::IsFullscreenGroup()
|
|
{
|
|
return m_parentGroup->IsFullscreenGroup();
|
|
}
|
|
|
|
C4JRender::eViewportType UILayer::getViewport()
|
|
{
|
|
return m_parentGroup->GetViewportType();
|
|
}
|
|
|
|
|
|
void UILayer::handleUnlockFullVersion()
|
|
{
|
|
for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
|
|
{
|
|
(*it)->handleUnlockFullVersion();
|
|
}
|
|
}
|
|
|
|
void UILayer::PrintTotalMemoryUsage(__int64 &totalStatic, __int64 &totalDynamic)
|
|
{
|
|
__int64 layerStatic = 0;
|
|
__int64 layerDynamic = 0;
|
|
for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
|
|
{
|
|
(*it)->PrintTotalMemoryUsage(layerStatic, layerDynamic);
|
|
}
|
|
for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
|
|
{
|
|
(*it)->PrintTotalMemoryUsage(layerStatic, layerDynamic);
|
|
}
|
|
app.DebugPrintf(app.USER_SR, " \\- Layer static: %d , Layer dynamic: %d\n", layerStatic, layerDynamic);
|
|
totalStatic += layerStatic;
|
|
totalDynamic += layerDynamic;
|
|
}
|
|
|
|
// Returns the first scene of given type if it exists, NULL otherwise
|
|
UIScene *UILayer::FindScene(EUIScene sceneType)
|
|
{
|
|
for (int i = 0; i < m_sceneStack.size(); i++)
|
|
{
|
|
if (m_sceneStack[i]->getSceneType() == sceneType)
|
|
{
|
|
return m_sceneStack[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|