the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at main 913 lines 24 kB view raw
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}