the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
1#include "stdafx.h"
2#include "UI.h"
3#include "UILayer.h"
4#include "UIScene.h"
5
6UILayer::UILayer(UIGroup *parent)
7{
8 m_parentGroup = parent;
9 m_hasFocus = false;
10 m_bMenuDisplayed = false;
11 m_bPauseMenuDisplayed = false;
12 m_bContainerMenuDisplayed = false;
13 m_bIgnoreAutosaveMenuDisplayed = false;
14 m_bIgnorePlayerJoinMenuDisplayed = false;
15}
16
17void UILayer::tick()
18{
19 // 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
20 vector<UIScene *>scenesToDeleteCopy;
21 for( AUTO_VAR(it,m_scenesToDelete.begin()); it != m_scenesToDelete.end(); it++)
22 {
23 UIScene *scene = (*it);
24 scenesToDeleteCopy.push_back(scene);
25 }
26 m_scenesToDelete.clear();
27
28 // 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.
29 for( AUTO_VAR(it,scenesToDeleteCopy.begin()); it != scenesToDeleteCopy.end(); it++)
30 {
31 UIScene *scene = (*it);
32 if( scene->isReadyToDelete())
33 {
34 delete scene;
35 }
36 else
37 {
38 m_scenesToDelete.push_back(scene);
39 }
40 }
41
42 while (!m_scenesToDestroy.empty())
43 {
44 UIScene *scene = m_scenesToDestroy.back();
45 m_scenesToDestroy.pop_back();
46 scene->destroyMovie();
47 }
48 m_scenesToDestroy.clear();
49
50 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
51 {
52 (*it)->tick();
53 }
54 // Note: reverse iterator, the last element is the top of the stack
55 int sceneIndex = m_sceneStack.size() - 1;
56 //for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
57 while( sceneIndex >= 0 && sceneIndex < m_sceneStack.size() )
58 {
59 //(*it)->tick();
60 UIScene *scene = m_sceneStack[sceneIndex];
61 scene->tick();
62 --sceneIndex;
63 // TODO: We may wish to ignore ticking the rest of the stack based on this scene
64 }
65}
66
67void UILayer::render(S32 width, S32 height, C4JRender::eViewportType viewport)
68{
69 if(!ui.IsExpectingOrReloadingSkin())
70 {
71 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
72 {
73 AUTO_VAR(itRef,m_componentRefCount.find((*it)->getSceneType()));
74 if(itRef != m_componentRefCount.end() && itRef->second.second)
75 {
76 if((*it)->isVisible() )
77 {
78 PIXBeginNamedEvent(0, "Rendering component %d", (*it)->getSceneType() );
79 (*it)->render(width, height,viewport);
80 PIXEndNamedEvent();
81 }
82 }
83 }
84 }
85 if(!m_sceneStack.empty())
86 {
87 int lowestRenderable = m_sceneStack.size() - 1;
88 for(;lowestRenderable >= 0; --lowestRenderable)
89 {
90 if(m_sceneStack[lowestRenderable]->hidesLowerScenes()) break;
91 }
92 if(lowestRenderable < 0) lowestRenderable = 0;
93 for(;lowestRenderable < m_sceneStack.size(); ++lowestRenderable)
94 {
95 if(m_sceneStack[lowestRenderable]->isVisible() && (!ui.IsExpectingOrReloadingSkin() || m_sceneStack[lowestRenderable]->getSceneType()==eUIScene_Timer))
96 {
97 PIXBeginNamedEvent(0, "Rendering scene %d", m_sceneStack[lowestRenderable]->getSceneType() );
98 m_sceneStack[lowestRenderable]->render(width, height,viewport);
99 PIXEndNamedEvent();
100 }
101 }
102 }
103}
104
105bool UILayer::IsSceneInStack(EUIScene scene)
106{
107 bool inStack = false;
108 for(int i = m_sceneStack.size() - 1;i >= 0; --i)
109 {
110 if(m_sceneStack[i]->getSceneType() == scene)
111 {
112 inStack = true;
113 break;
114 }
115 }
116 return inStack;
117}
118
119bool UILayer::HasFocus(int iPad)
120{
121 bool hasFocus = false;
122 if(m_hasFocus)
123 {
124 for(int i = m_sceneStack.size() - 1;i >= 0; --i)
125 {
126 if(m_sceneStack[i]->stealsFocus() )
127 {
128 if(m_sceneStack[i]->hasFocus(iPad))
129 {
130 hasFocus = true;
131 }
132 break;
133 }
134 }
135 }
136 return hasFocus;
137}
138
139bool UILayer::hidesLowerScenes()
140{
141 bool hidesScenes = false;
142 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
143 {
144 if((*it)->hidesLowerScenes())
145 {
146 hidesScenes = true;
147 break;
148 }
149 }
150 if(!hidesScenes && !m_sceneStack.empty())
151 {
152 for(int i = m_sceneStack.size() - 1;i >= 0; --i)
153 {
154 if(m_sceneStack[i]->hidesLowerScenes())
155 {
156 hidesScenes = true;
157 break;
158 }
159 }
160 }
161 return hidesScenes;
162}
163
164void UILayer::getRenderDimensions(S32 &width, S32 &height)
165{
166 m_parentGroup->getRenderDimensions(width, height);
167}
168
169void UILayer::DestroyAll()
170{
171 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
172 {
173 (*it)->destroyMovie();
174 }
175 for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
176 {
177 (*it)->destroyMovie();
178 }
179}
180
181void UILayer::ReloadAll(bool force)
182{
183 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
184 {
185 (*it)->reloadMovie(force);
186 }
187 if(!m_sceneStack.empty())
188 {
189 int lowestRenderable = 0;
190 for(;lowestRenderable < m_sceneStack.size(); ++lowestRenderable)
191 {
192 m_sceneStack[lowestRenderable]->reloadMovie(force);
193 }
194 }
195}
196
197bool UILayer::GetMenuDisplayed()
198{
199 return m_bMenuDisplayed;
200}
201
202bool UILayer::NavigateToScene(int iPad, EUIScene scene, void *initData)
203{
204 UIScene *newScene = NULL;
205 switch(scene)
206 {
207 // Debug
208#ifdef _DEBUG_MENUS_ENABLED
209 case eUIScene_DebugOverlay:
210 newScene = new UIScene_DebugOverlay(iPad, initData, this);
211 break;
212 case eUIScene_DebugSetCamera:
213 newScene = new UIScene_DebugSetCamera(iPad, initData, this);
214 break;
215 case eUIScene_DebugCreateSchematic:
216 newScene = new UIScene_DebugCreateSchematic(iPad, initData, this);
217 break;
218#endif
219 case eUIScene_DebugOptions:
220 newScene = new UIScene_DebugOptionsMenu(iPad, initData, this);
221 break;
222
223 // Containers
224 case eUIScene_InventoryMenu:
225 newScene = new UIScene_InventoryMenu(iPad, initData, this);
226 break;
227 case eUIScene_CreativeMenu:
228 newScene = new UIScene_CreativeMenu(iPad, initData, this);
229 break;
230 case eUIScene_ContainerMenu:
231 case eUIScene_LargeContainerMenu:
232 newScene = new UIScene_ContainerMenu(iPad, initData, this);
233 break;
234 case eUIScene_BrewingStandMenu:
235 newScene = new UIScene_BrewingStandMenu(iPad, initData, this);
236 break;
237 case eUIScene_DispenserMenu:
238 newScene = new UIScene_DispenserMenu(iPad, initData, this);
239 break;
240 case eUIScene_EnchantingMenu:
241 newScene = new UIScene_EnchantingMenu(iPad, initData, this);
242 break;
243 case eUIScene_FurnaceMenu:
244 newScene = new UIScene_FurnaceMenu(iPad, initData, this);
245 break;
246 case eUIScene_Crafting2x2Menu:
247 case eUIScene_Crafting3x3Menu:
248 newScene = new UIScene_CraftingMenu(iPad, initData, this);
249 break;
250 case eUIScene_TradingMenu:
251 newScene = new UIScene_TradingMenu(iPad, initData, this);
252 break;
253 case eUIScene_AnvilMenu:
254 newScene = new UIScene_AnvilMenu(iPad, initData, this);
255 break;
256 case eUIScene_HopperMenu:
257 newScene = new UIScene_HopperMenu(iPad, initData, this);
258 break;
259 case eUIScene_BeaconMenu:
260 newScene = new UIScene_BeaconMenu(iPad, initData, this);
261 break;
262 case eUIScene_HorseMenu:
263 newScene = new UIScene_HorseInventoryMenu(iPad, initData, this);
264 break;
265 case eUIScene_FireworksMenu:
266 newScene = new UIScene_FireworksMenu(iPad, initData, this);
267 break;
268
269 // Help and Options
270 case eUIScene_HelpAndOptionsMenu:
271 newScene = new UIScene_HelpAndOptionsMenu(iPad, initData, this);
272 break;
273 case eUIScene_SettingsMenu:
274 newScene = new UIScene_SettingsMenu(iPad, initData, this);
275 break;
276 case eUIScene_SettingsOptionsMenu:
277 newScene = new UIScene_SettingsOptionsMenu(iPad, initData, this);
278 break;
279 case eUIScene_SettingsAudioMenu:
280 newScene = new UIScene_SettingsAudioMenu(iPad, initData, this);
281 break;
282 case eUIScene_SettingsControlMenu:
283 newScene = new UIScene_SettingsControlMenu(iPad, initData, this);
284 break;
285 case eUIScene_SettingsGraphicsMenu:
286 newScene = new UIScene_SettingsGraphicsMenu(iPad, initData, this);
287 break;
288 case eUIScene_SettingsUIMenu:
289 newScene = new UIScene_SettingsUIMenu(iPad, initData, this);
290 break;
291 case eUIScene_SkinSelectMenu:
292 newScene = new UIScene_SkinSelectMenu(iPad, initData, this);
293 break;
294 case eUIScene_HowToPlayMenu:
295 newScene = new UIScene_HowToPlayMenu(iPad, initData, this);
296 break;
297 case eUIScene_LanguageSelector:
298 newScene = new UIScene_LanguageSelector(iPad, initData, this);
299 break;
300 case eUIScene_HowToPlay:
301 newScene = new UIScene_HowToPlay(iPad, initData, this);
302 break;
303 case eUIScene_ControlsMenu:
304 newScene = new UIScene_ControlsMenu(iPad, initData, this);
305 break;
306 case eUIScene_ReinstallMenu:
307 newScene = new UIScene_ReinstallMenu(iPad, initData, this);
308 break;
309 case eUIScene_Credits:
310 newScene = new UIScene_Credits(iPad, initData, this);
311 break;
312
313
314 // Other in-game
315 case eUIScene_PauseMenu:
316 newScene = new UIScene_PauseMenu(iPad, initData, this);
317 break;
318 case eUIScene_DeathMenu:
319 newScene = new UIScene_DeathMenu(iPad, initData, this);
320 break;
321 case eUIScene_ConnectingProgress:
322 newScene = new UIScene_ConnectingProgress(iPad, initData, this);
323 break;
324 case eUIScene_SignEntryMenu:
325 newScene = new UIScene_SignEntryMenu(iPad, initData, this);
326 break;
327 case eUIScene_InGameInfoMenu:
328 newScene = new UIScene_InGameInfoMenu(iPad, initData, this);
329 break;
330 case eUIScene_InGameHostOptionsMenu:
331 if (IsSceneInStack(eUIScene_InGameHostOptionsMenu)) {
332 app.DebugPrintf("Skipped eUIScene_InGameHostOptionsMenu, we have already this tab!");
333 return false;
334 }
335 newScene = new UIScene_InGameHostOptionsMenu(iPad, initData, this);
336 break;
337 case eUIScene_InGamePlayerOptionsMenu:
338 newScene = new UIScene_InGamePlayerOptionsMenu(iPad, initData, this);
339 break;
340#if defined(_XBOX_ONE) || defined(__ORBIS__)
341 case eUIScene_InGameSaveManagementMenu:
342 newScene = new UIScene_InGameSaveManagementMenu(iPad, initData, this);
343 break;
344#endif
345 case eUIScene_TeleportMenu:
346 newScene = new UIScene_TeleportMenu(iPad, initData, this);
347 break;
348 case eUIScene_EndPoem:
349 if(IsSceneInStack(eUIScene_EndPoem))
350 {
351 app.DebugPrintf("Skipped EndPoem as one was already showing\n");
352 return false;
353 }
354 else
355 {
356 newScene = new UIScene_EndPoem(iPad, initData, this);
357 }
358 break;
359
360
361 // Frontend
362 case eUIScene_TrialExitUpsell:
363 newScene = new UIScene_TrialExitUpsell(iPad, initData, this);
364 break;
365 case eUIScene_Intro:
366 newScene = new UIScene_Intro(iPad, initData, this);
367 break;
368 case eUIScene_SaveMessage:
369 newScene = new UIScene_SaveMessage(iPad, initData, this);
370 break;
371 case eUIScene_MainMenu:
372 newScene = new UIScene_MainMenu(iPad, initData, this);
373 break;
374 case eUIScene_LoadOrJoinMenu:
375 newScene = new UIScene_LoadOrJoinMenu(iPad, initData, this);
376 break;
377 case eUIScene_LoadMenu:
378 newScene = new UIScene_LoadMenu(iPad, initData, this);
379 break;
380 case eUIScene_JoinMenu:
381 newScene = new UIScene_JoinMenu(iPad, initData, this);
382 break;
383 case eUIScene_CreateWorldMenu:
384 newScene = new UIScene_CreateWorldMenu(iPad, initData, this);
385 break;
386 case eUIScene_LaunchMoreOptionsMenu:
387 newScene = new UIScene_LaunchMoreOptionsMenu(iPad, initData, this);
388 break;
389 case eUIScene_FullscreenProgress:
390 newScene = new UIScene_FullscreenProgress(iPad, initData, this);
391 break;
392 case eUIScene_LeaderboardsMenu:
393 newScene = new UIScene_LeaderboardsMenu(iPad, initData, this);
394 break;
395 case eUIScene_DLCMainMenu:
396 newScene = new UIScene_DLCMainMenu(iPad, initData, this);
397 break;
398 case eUIScene_DLCOffersMenu:
399 newScene = new UIScene_DLCOffersMenu(iPad, initData, this);
400 break;
401 case eUIScene_EULA:
402 newScene = new UIScene_EULA(iPad, initData, this);
403 break;
404 case eUIScene_NewUpdateMessage:
405 newScene = new UIScene_NewUpdateMessage(iPad, initData, this);
406 break;
407
408 // Other
409 case eUIScene_Keyboard:
410 newScene = new UIScene_Keyboard(iPad, initData, this);
411 break;
412 case eUIScene_QuadrantSignin:
413 newScene = new UIScene_QuadrantSignin(iPad, initData, this);
414 break;
415 case eUIScene_MessageBox:
416 if(IsSceneInStack(eUIScene_MessageBox))
417 {
418 app.DebugPrintf("Skipped MessageBox as one was already showing\n");
419 return false;
420 }
421 else
422 {
423 newScene = new UIScene_MessageBox(iPad, initData, this);
424 }
425 break;
426 case eUIScene_Timer:
427 newScene = new UIScene_Timer(iPad, initData, this);
428 break;
429 };
430
431 if(newScene == NULL)
432 {
433 app.DebugPrintf("WARNING: Scene %d was not created. Add it to UILayer::NavigateToScene\n", scene);
434 return false;
435 }
436
437 if(m_sceneStack.size() > 0)
438 {
439 newScene->setBackScene(m_sceneStack[m_sceneStack.size()-1]);
440 }
441
442 m_sceneStack.push_back(newScene);
443
444 updateFocusState();
445
446 newScene->tick();
447
448 return true;
449}
450
451bool UILayer::NavigateBack(int iPad, EUIScene eScene)
452{
453 if(m_sceneStack.size() == 0) return false;
454
455 bool navigated = false;
456 if(eScene < eUIScene_COUNT)
457 {
458 UIScene *scene = NULL;
459 do
460 {
461 scene = m_sceneStack.back();
462 if(scene->getSceneType() == eScene)
463 {
464 navigated = true;
465 break;
466 }
467 else
468 {
469 if(scene->hasFocus(iPad))
470 {
471 removeScene(scene);
472 }
473 else
474 {
475 // No focus on the top scene, so this use shouldn't be navigating!
476 break;
477 }
478 }
479 } while(m_sceneStack.size() > 0);
480
481 }
482 else
483 {
484 UIScene *scene = m_sceneStack.back();
485 if(scene->hasFocus(iPad))
486 {
487 removeScene(scene);
488 navigated = true;
489 }
490 }
491 return navigated;
492}
493
494void UILayer::showComponent(int iPad, EUIScene scene, bool show)
495{
496 AUTO_VAR(it,m_componentRefCount.find(scene));
497 if(it != m_componentRefCount.end())
498 {
499 it->second.second = show;
500 return;
501 }
502 if(show) addComponent(iPad,scene);
503}
504
505bool UILayer::isComponentVisible(EUIScene scene)
506{
507 bool visible = false;
508 AUTO_VAR(it,m_componentRefCount.find(scene));
509 if(it != m_componentRefCount.end())
510 {
511 visible = it->second.second;
512 }
513 return visible;
514}
515
516UIScene *UILayer::addComponent(int iPad, EUIScene scene, void *initData)
517{
518 AUTO_VAR(it,m_componentRefCount.find(scene));
519 if(it != m_componentRefCount.end())
520 {
521 ++it->second.first;
522
523 for(AUTO_VAR(itComp,m_components.begin()); itComp != m_components.end(); ++itComp)
524 {
525 if( (*itComp)->getSceneType() == scene )
526 {
527 return *itComp;
528 }
529 }
530 return NULL;
531 }
532 UIScene *newScene = NULL;
533
534 switch(scene)
535 {
536 case eUIComponent_Panorama:
537 newScene = new UIComponent_Panorama(iPad, initData, this);
538 m_componentRefCount[scene] = pair<int,bool>(1,true);
539 break;
540 case eUIComponent_DebugUIConsole:
541 newScene = new UIComponent_DebugUIConsole(iPad, initData, this);
542 m_componentRefCount[scene] = pair<int,bool>(1,true);
543 break;
544 case eUIComponent_DebugUIMarketingGuide:
545 newScene = new UIComponent_DebugUIMarketingGuide(iPad, initData, this);
546 m_componentRefCount[scene] = pair<int,bool>(1,true);
547 break;
548 case eUIComponent_Logo:
549 newScene = new UIComponent_Logo(iPad, initData, this);
550 m_componentRefCount[scene] = pair<int,bool>(1,true);
551 break;
552 case eUIComponent_Tooltips:
553 newScene = new UIComponent_Tooltips(iPad, initData, this);
554 m_componentRefCount[scene] = pair<int,bool>(1,true);
555 break;
556 case eUIComponent_TutorialPopup:
557 newScene = new UIComponent_TutorialPopup(iPad, initData, this);
558 // Start hidden
559 m_componentRefCount[scene] = pair<int,bool>(1,false);
560 break;
561 case eUIScene_HUD:
562 newScene = new UIScene_HUD(iPad, initData, this);
563 // Start hidden
564 m_componentRefCount[scene] = pair<int,bool>(1,false);
565 break;
566 case eUIComponent_Chat:
567 newScene = new UIComponent_Chat(iPad, initData, this);
568 m_componentRefCount[scene] = pair<int,bool>(1,true);
569 break;
570 case eUIComponent_PressStartToPlay:
571 newScene = new UIComponent_PressStartToPlay(iPad, initData, this);
572 m_componentRefCount[scene] = pair<int,bool>(1,true);
573 break;
574 case eUIComponent_MenuBackground:
575 newScene = new UIComponent_MenuBackground(iPad, initData, this);
576 m_componentRefCount[scene] = pair<int,bool>(1,true);
577 break;
578 };
579
580 if(newScene == NULL) return NULL;
581
582 m_components.push_back(newScene);
583
584 return newScene;
585}
586
587void UILayer::removeComponent(EUIScene scene)
588{
589 AUTO_VAR(it,m_componentRefCount.find(scene));
590 if(it != m_componentRefCount.end())
591 {
592 --it->second.first;
593
594 if(it->second.first <= 0)
595 {
596 m_componentRefCount.erase(it);
597 for(AUTO_VAR(compIt, m_components.begin()) ; compIt != m_components.end(); )
598 {
599 if( (*compIt)->getSceneType() == scene)
600 {
601#ifdef __PSVITA__
602 // remove any touchboxes
603 ui.TouchBoxesClear((*compIt));
604#endif
605 m_scenesToDelete.push_back((*compIt));
606 (*compIt)->handleDestroy(); // For anything that might require the pointer be valid
607 compIt = m_components.erase(compIt);
608 }
609 else
610 {
611 ++compIt;
612 }
613 }
614 }
615 }
616}
617
618void UILayer::removeScene(UIScene *scene)
619{
620#ifdef __PSVITA__
621 // remove any touchboxes
622 ui.TouchBoxesClear(scene);
623#endif
624
625 AUTO_VAR(newEnd, std::remove(m_sceneStack.begin(), m_sceneStack.end(), scene) );
626 m_sceneStack.erase(newEnd, m_sceneStack.end());
627
628 m_scenesToDelete.push_back(scene);
629
630 scene->handleDestroy(); // For anything that might require the pointer be valid
631
632 bool hadFocus = m_hasFocus;
633 updateFocusState();
634
635 // If this layer has focus, pass it on
636 if (m_hasFocus || hadFocus)
637 {
638 m_hasFocus = false;
639 m_parentGroup->UpdateFocusState();
640 }
641}
642
643void UILayer::closeAllScenes()
644{
645 vector<UIScene *> temp;
646 temp.insert(temp.end(), m_sceneStack.begin(), m_sceneStack.end());
647 m_sceneStack.clear();
648 for(AUTO_VAR(it, temp.begin()); it != temp.end(); ++it)
649 {
650#ifdef __PSVITA__
651 // remove any touchboxes
652 ui.TouchBoxesClear(*it);
653#endif
654 m_scenesToDelete.push_back(*it);
655 (*it)->handleDestroy(); // For anything that might require the pointer be valid
656 }
657
658 updateFocusState();
659
660 // If this layer has focus, pass it on
661 if (m_hasFocus)
662 {
663 m_hasFocus = false;
664 m_parentGroup->UpdateFocusState();
665 }
666}
667
668// Get top scene on stack (or NULL if stack is empty)
669UIScene *UILayer::GetTopScene()
670{
671 if(m_sceneStack.size() == 0)
672 {
673 return NULL;
674 }
675 else
676 {
677 return m_sceneStack[m_sceneStack.size()-1];
678 }
679}
680
681// Updates layer focus state if no error message is present (unless this is the error layer)
682bool UILayer::updateFocusState(bool allowedFocus /* = false */)
683{
684 // If haveFocus is false, request it
685 if (!allowedFocus)
686 {
687 // To update focus in this layer we need to request focus from group
688 // Focus will be denied if there's an upper layer that needs focus
689 allowedFocus = m_parentGroup->RequestFocus(this);
690 }
691
692 m_bMenuDisplayed = false;
693 m_bPauseMenuDisplayed = false;
694 m_bContainerMenuDisplayed = false;
695 m_bIgnoreAutosaveMenuDisplayed = false;
696 m_bIgnorePlayerJoinMenuDisplayed = false;
697
698 bool layerFocusSet = false;
699 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
700 {
701 UIScene *scene = *it;
702
703 // UPDATE FOCUS STATES
704 if(!layerFocusSet && allowedFocus && scene->stealsFocus())
705 {
706 scene->gainFocus();
707 layerFocusSet = true;
708 }
709 else
710 {
711 scene->loseFocus();
712 if(allowedFocus && app.GetGameStarted())
713 {
714 // 4J Stu - This is a memory optimisation so we don't keep scenes loaded in memory all the time
715 // This is required for PS3 (and likely Vita), but I'm removing it on XboxOne so that we can avoid
716 // the scene creation time (which can be >0.5s) since we have the memory to spare
717#ifndef _XBOX_ONE
718 m_scenesToDestroy.push_back(scene);
719#endif
720 }
721
722 if (scene->getSceneType() == eUIScene_SettingsOptionsMenu)
723 {
724 scene->loseFocus();
725 m_scenesToDestroy.push_back(scene);
726 }
727 }
728
729 /// UPDATE STACK STATES
730
731 // 4J-PB - this should just be true
732 m_bMenuDisplayed=true;
733
734 EUIScene sceneType = scene->getSceneType();
735 switch(sceneType)
736 {
737 case eUIScene_PauseMenu:
738 m_bPauseMenuDisplayed = true;
739 break;
740 case eUIScene_Crafting2x2Menu:
741 case eUIScene_Crafting3x3Menu:
742 case eUIScene_FurnaceMenu:
743 case eUIScene_ContainerMenu:
744 case eUIScene_LargeContainerMenu:
745 case eUIScene_InventoryMenu:
746 case eUIScene_CreativeMenu:
747 case eUIScene_DispenserMenu:
748 case eUIScene_BrewingStandMenu:
749 case eUIScene_EnchantingMenu:
750 case eUIScene_TradingMenu:
751 case eUIScene_HopperMenu:
752 case eUIScene_HorseMenu:
753 case eUIScene_FireworksMenu:
754 case eUIScene_BeaconMenu:
755 case eUIScene_AnvilMenu:
756 m_bContainerMenuDisplayed=true;
757
758 // Intentional fall-through
759 case eUIScene_DeathMenu:
760 case eUIScene_FullscreenProgress:
761 case eUIScene_SignEntryMenu:
762 case eUIScene_EndPoem:
763 m_bIgnoreAutosaveMenuDisplayed = true;
764 break;
765 }
766
767 switch(sceneType)
768 {
769 case eUIScene_FullscreenProgress:
770 case eUIScene_EndPoem:
771 case eUIScene_Credits:
772 case eUIScene_LeaderboardsMenu:
773 m_bIgnorePlayerJoinMenuDisplayed = true;
774 break;
775 }
776 }
777 m_hasFocus = layerFocusSet;
778
779 return m_hasFocus;
780}
781
782#ifdef __PSVITA__
783UIScene *UILayer::getCurrentScene()
784{
785 // Note: reverse iterator, the last element is the top of the stack
786 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
787 {
788 UIScene *scene = *it;
789 // 4J-PB - only used on Vita, so iPad 0 is fine
790 if(scene->hasFocus(0) && scene->canHandleInput())
791 {
792 return scene;
793 }
794}
795
796 return NULL;
797}
798#endif
799
800void UILayer::handleInput(int iPad, int key, bool repeat, bool pressed, bool released, bool &handled)
801{
802 // Note: reverse iterator, the last element is the top of the stack
803 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
804 {
805 UIScene *scene = *it;
806 if(scene->hasFocus(iPad) && scene->canHandleInput())
807 {
808 // 4J-PB - ignore repeats of action ABXY buttons
809 // fix for PS3 213 - [MAIN MENU] Holding down buttons will continue to activate every prompt.
810 // 4J Stu - Changed this slightly to add the allowRepeat function so we can allow repeats in the crafting menu
811 if(repeat && !scene->allowRepeat(key) )
812 {
813 return;
814 }
815 scene->handleInput(iPad, key, repeat, pressed, released, handled);
816 }
817
818 // Fix for PS3 #444 - [IN GAME] If the user keeps pressing CROSS while on the 'Save Game' screen the title will crash.
819 handled = handled || scene->hidesLowerScenes() || scene->blocksInput();
820 if(handled ) break;
821 }
822
823 // Components can't take input or focus
824}
825
826void UILayer::HandleDLCMountingComplete()
827{
828 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
829 {
830 UIScene *topScene = *it;
831 app.DebugPrintf("UILayer::HandleDLCMountingComplete - topScene\n");
832 topScene->HandleDLCMountingComplete();
833 }
834}
835
836void UILayer::HandleDLCInstalled()
837{
838 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
839 {
840 UIScene *topScene = *it;
841 topScene->HandleDLCInstalled();
842 }
843}
844
845#ifdef _XBOX_ONE
846void UILayer::HandleDLCLicenseChange()
847{
848 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
849 {
850 UIScene *topScene = *it;
851 topScene->HandleDLCLicenseChange();
852 }
853}
854#endif
855
856void UILayer::HandleMessage(EUIMessage message, void *data)
857{
858 for(AUTO_VAR(it,m_sceneStack.rbegin()); it != m_sceneStack.rend(); ++it)
859 {
860 UIScene *topScene = *it;
861 topScene->HandleMessage(message, data);
862 }
863}
864
865bool UILayer::IsFullscreenGroup()
866{
867 return m_parentGroup->IsFullscreenGroup();
868}
869
870C4JRender::eViewportType UILayer::getViewport()
871{
872 return m_parentGroup->GetViewportType();
873}
874
875
876void UILayer::handleUnlockFullVersion()
877{
878 for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
879 {
880 (*it)->handleUnlockFullVersion();
881 }
882}
883
884void UILayer::PrintTotalMemoryUsage(__int64 &totalStatic, __int64 &totalDynamic)
885{
886 __int64 layerStatic = 0;
887 __int64 layerDynamic = 0;
888 for(AUTO_VAR(it,m_components.begin()); it != m_components.end(); ++it)
889 {
890 (*it)->PrintTotalMemoryUsage(layerStatic, layerDynamic);
891 }
892 for(AUTO_VAR(it, m_sceneStack.begin()); it != m_sceneStack.end(); ++it)
893 {
894 (*it)->PrintTotalMemoryUsage(layerStatic, layerDynamic);
895 }
896 app.DebugPrintf(app.USER_SR, " \\- Layer static: %d , Layer dynamic: %d\n", layerStatic, layerDynamic);
897 totalStatic += layerStatic;
898 totalDynamic += layerDynamic;
899}
900
901// Returns the first scene of given type if it exists, NULL otherwise
902UIScene *UILayer::FindScene(EUIScene sceneType)
903{
904 for (int i = 0; i < m_sceneStack.size(); i++)
905 {
906 if (m_sceneStack[i]->getSceneType() == sceneType)
907 {
908 return m_sceneStack[i];
909 }
910 }
911
912 return NULL;
913}