123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include "EditorDefs.h"
- #include "GameEngine.h"
- // Qt
- #include <QMessageBox>
- #include <QThread>
- // AzCore
- #include <AzCore/Component/ComponentApplication.h>
- #include <AzCore/IO/IStreamer.h>
- #include <AzCore/IO/Streamer/FileRequest.h>
- #include <AzCore/Serialization/Locale.h>
- #include <AzCore/std/parallel/binary_semaphore.h>
- #include <AzCore/Console/IConsole.h>
- // AzFramework
- #include <AzFramework/Asset/AssetSystemBus.h>
- #include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
- #include <AzFramework/Input/Devices/Keyboard/InputDeviceKeyboard.h>
- #include <AzFramework/Input/Buses/Requests/InputSystemCursorRequestBus.h>
- #include <AzFramework/Archive/IArchive.h>
- // Editor
- #include "IEditorImpl.h"
- #include "CryEditDoc.h"
- #include "Settings.h"
- // CryCommon
- #include <CryCommon/MainThreadRenderRequestBus.h>
- // Editor
- #include "CryEdit.h"
- #include "ViewManager.h"
- #include "AnimationContext.h"
- #include "MainWindow.h"
- // Implementation of System Callback structure.
- struct SSystemUserCallback
- : public ISystemUserCallback
- {
- SSystemUserCallback(IInitializeUIInfo* logo) : m_threadErrorHandler(this) { m_pLogo = logo; };
- void OnSystemConnect(ISystem* pSystem) override
- {
- ModuleInitISystem(pSystem, "Editor");
- }
- bool OnError(const char* szErrorString) override
- {
- // since we show a message box, we have to use the GUI thread
- if (QThread::currentThread() != qApp->thread())
- {
- bool result = false;
- QMetaObject::invokeMethod(&m_threadErrorHandler, "OnError", Qt::BlockingQueuedConnection, Q_RETURN_ARG(bool, result), Q_ARG(const char*, szErrorString));
- return result;
- }
- if (szErrorString)
- {
- Log(szErrorString);
- }
- if (GetIEditor()->IsInTestMode())
- {
- exit(1);
- }
- char str[4096];
- if (szErrorString)
- {
- azsnprintf(str, 4096, "%s\r\nSave Level Before Exiting the Editor?", szErrorString);
- }
- else
- {
- azsnprintf(str, 4096, "Unknown Error\r\nSave Level Before Exiting the Editor?");
- }
- int res = IDNO;
- ICVar* pCVar = gEnv->pConsole ? gEnv->pConsole->GetCVar("sys_no_crash_dialog") : nullptr;
- if (!pCVar || pCVar->GetIVal() == 0)
- {
- res = QMessageBox::critical(QApplication::activeWindow(), QObject::tr("Engine Error"), str, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
- }
- if (res == QMessageBox::Yes || res == QMessageBox::No)
- {
- if (res == QMessageBox::Yes)
- {
- if (GetIEditor()->SaveDocument())
- {
- QMessageBox::information(QApplication::activeWindow(), QObject::tr("Save"), QObject::tr("Level has been successfully saved!\r\nPress Ok to terminate Editor."));
- }
- }
- }
- return true;
- }
- bool OnSaveDocument() override
- {
- bool success = false;
- if (GetIEditor())
- {
- // Turn off save backup as we force a backup before reaching this point
- bool prevSaveBackup = gSettings.bBackupOnSave;
- gSettings.bBackupOnSave = false;
- success = GetIEditor()->SaveDocument();
- gSettings.bBackupOnSave = prevSaveBackup;
- }
- return success;
- }
- bool OnBackupDocument() override
- {
- CCryEditDoc* level = GetIEditor() ? GetIEditor()->GetDocument() : nullptr;
- if (level)
- {
- return level->BackupBeforeSave(true);
- }
- return false;
- }
- void OnProcessSwitch() override
- {
- if (GetIEditor()->IsInGameMode())
- {
- GetIEditor()->SetInGameMode(false);
- }
- }
- void OnInitProgress(const char* sProgressMsg) override
- {
- if (m_pLogo)
- {
- m_pLogo->SetInfoText(sProgressMsg);
- }
- }
- void OnSplashScreenDone()
- {
- m_pLogo = nullptr;
- }
- private:
- IInitializeUIInfo* m_pLogo;
- ThreadedOnErrorHandler m_threadErrorHandler;
- };
- ThreadedOnErrorHandler::ThreadedOnErrorHandler(ISystemUserCallback* callback)
- : m_userCallback(callback)
- {
- moveToThread(qApp->thread());
- }
- ThreadedOnErrorHandler::~ThreadedOnErrorHandler()
- {
- }
- bool ThreadedOnErrorHandler::OnError(const char* error)
- {
- return m_userCallback->OnError(error);
- }
- //! This class will be used by CSystem to find out whether the negotiation with the assetprocessor failed
- class AssetProcessConnectionStatus
- : public AzFramework::AssetSystemConnectionNotificationsBus::Handler
- {
- public:
- AssetProcessConnectionStatus()
- {
- AzFramework::AssetSystemConnectionNotificationsBus::Handler::BusConnect();
- };
- ~AssetProcessConnectionStatus() override
- {
- AzFramework::AssetSystemConnectionNotificationsBus::Handler::BusDisconnect();
- }
- //! Notifies listeners that connection to the Asset Processor failed
- void ConnectionFailed() override
- {
- m_connectionFailed = true;
- }
- void NegotiationFailed() override
- {
- m_negotiationFailed = true;
- }
- bool CheckConnectionFailed()
- {
- return m_connectionFailed;
- }
- bool CheckNegotiationFailed()
- {
- return m_negotiationFailed;
- }
- private:
- bool m_connectionFailed = false;
- bool m_negotiationFailed = false;
- };
- AZ_PUSH_DISABLE_WARNING(4273, "-Wunknown-warning-option")
- CGameEngine::CGameEngine()
- : m_bIgnoreUpdates(false)
- , m_ePendingGameMode(ePGM_NotPending)
- , m_modalWindowDismisser(nullptr)
- AZ_POP_DISABLE_WARNING
- {
- m_pISystem = nullptr;
- m_bLevelLoaded = false;
- m_bInGameMode = false;
- m_bSimulationMode = false;
- m_bSyncPlayerPosition = true;
- m_hSystemHandle.reset(nullptr);
- m_bJustCreated = false;
- m_levelName = "Untitled";
- m_levelExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
- m_playerViewTM.SetIdentity();
- GetIEditor()->RegisterNotifyListener(this);
- }
- AZ_PUSH_DISABLE_WARNING(4273, "-Wunknown-warning-option")
- CGameEngine::~CGameEngine()
- {
- AZ_POP_DISABLE_WARNING
- GetIEditor()->UnregisterNotifyListener(this);
- m_pISystem->GetIMovieSystem()->SetCallback(nullptr);
- delete m_pISystem;
- m_pISystem = nullptr;
- m_hSystemHandle.reset(nullptr);
- delete m_pSystemUserCallback;
- }
- static int ed_killmemory_size;
- static int ed_indexfiles;
- void KillMemory(IConsoleCmdArgs* /* pArgs */)
- {
- while (true)
- {
- const int kLimit = 10000000;
- int size;
- if (ed_killmemory_size > 0)
- {
- size = ed_killmemory_size;
- }
- else
- {
- size = rand() * rand();
- size = size > kLimit ? kLimit : size;
- }
- new uint8[size];
- }
- }
- static void CmdGotoEditor(IConsoleCmdArgs* pArgs)
- {
- // Console commands are assumed to be in the culture invariant locale since they can come from data files.
- AZ::Locale::ScopedSerializationLocale scopedLocale;
- // feature is mostly useful for QA purposes, this works with the game "goto" command
- // this console command actually is used by the game command, the editor command shouldn't be used by the user
- int iArgCount = pArgs->GetArgCount();
- CViewManager* pViewManager = GetIEditor()->GetViewManager();
- CViewport* pRenderViewport = pViewManager->GetGameViewport();
- if (!pRenderViewport)
- {
- return;
- }
- float x, y, z, wx, wy, wz;
- if (iArgCount == 7
- && azsscanf(pArgs->GetArg(1), "%f", &x) == 1
- && azsscanf(pArgs->GetArg(2), "%f", &y) == 1
- && azsscanf(pArgs->GetArg(3), "%f", &z) == 1
- && azsscanf(pArgs->GetArg(4), "%f", &wx) == 1
- && azsscanf(pArgs->GetArg(5), "%f", &wy) == 1
- && azsscanf(pArgs->GetArg(6), "%f", &wz) == 1)
- {
- Matrix34 tm = pRenderViewport->GetViewTM();
- tm.SetTranslation(Vec3(x, y, z));
- tm.SetRotation33(Matrix33::CreateRotationXYZ(DEG2RAD(Ang3(wx, wy, wz))));
- pRenderViewport->SetViewTM(tm);
- }
- }
- AZ::Outcome<void, AZStd::string> CGameEngine::Init(
- bool bPreviewMode,
- bool bTestMode,
- const char* sInCmdLine,
- IInitializeUIInfo* logo,
- HWND hwndForInputSystem)
- {
- m_pSystemUserCallback = new SSystemUserCallback(logo);
- constexpr const char* crySystemLibraryName = AZ_TRAIT_OS_DYNAMIC_LIBRARY_PREFIX "CrySystem" AZ_TRAIT_OS_DYNAMIC_LIBRARY_EXTENSION;
- m_hSystemHandle = AZ::DynamicModuleHandle::Create(crySystemLibraryName);
- if (!m_hSystemHandle->Load(AZ::DynamicModuleHandle::LoadFlags::InitFuncRequired))
- {
- auto errorMessage = AZStd::string::format("%s Loading Failed", crySystemLibraryName);
- Error(errorMessage.c_str());
- return AZ::Failure(errorMessage);
- }
- PFNCREATESYSTEMINTERFACE pfnCreateSystemInterface =
- m_hSystemHandle->GetFunction<PFNCREATESYSTEMINTERFACE>("CreateSystemInterface");
- SSystemInitParams sip;
- sip.bEditor = true;
- sip.bDedicatedServer = false;
- sip.bPreview = bPreviewMode;
- sip.bTestMode = bTestMode;
- sip.hInstance = nullptr;
- #ifdef AZ_PLATFORM_MAC
- // Create a hidden QWidget. Would show a black window on macOS otherwise.
- auto window = new QWidget();
- QObject::connect(qApp, &QApplication::lastWindowClosed, window, &QWidget::deleteLater);
- sip.hWnd = (HWND)window->winId();
- #else
- sip.hWnd = hwndForInputSystem;
- #endif
- sip.pLogCallback = &m_logFile;
- sip.sLogFileName = "@log@/Editor.log";
- sip.pUserCallback = m_pSystemUserCallback;
- if (sInCmdLine)
- {
- azstrncpy(sip.szSystemCmdLine, AZ_COMMAND_LINE_LEN, sInCmdLine, AZ_COMMAND_LINE_LEN);
- if (strstr(sInCmdLine, "-export") || strstr(sInCmdLine, "/export") || strstr(sInCmdLine, "-autotest_mode"))
- {
- sip.bUnattendedMode = true;
- }
- }
- if (sip.bUnattendedMode)
- {
- m_modalWindowDismisser = AZStd::make_unique<ModalWindowDismisser>();
- }
- AssetProcessConnectionStatus apConnectionStatus;
- m_pISystem = pfnCreateSystemInterface(sip);
- if (!gEnv)
- {
- gEnv = m_pISystem->GetGlobalEnvironment();
- }
- if (!m_pISystem)
- {
- AZStd::string errorMessage = "Could not initialize CSystem. View the logs for more details.";
- gEnv = nullptr;
- Error("CreateSystemInterface Failed");
- return AZ::Failure(errorMessage);
- }
- if (apConnectionStatus.CheckNegotiationFailed())
- {
- auto errorMessage = AZStd::string::format("Negotiation with Asset Processor failed.\n"
- "Please ensure the Asset Processor is running on the same branch and try again.");
- gEnv = nullptr;
- return AZ::Failure(errorMessage);
- }
- if (apConnectionStatus.CheckConnectionFailed())
- {
- AzFramework::AssetSystem::ConnectionSettings connectionSettings;
- AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings);
- auto errorMessage = AZStd::string::format("Unable to connect to the local Asset Processor.\n\n"
- "The Asset Processor is either not running locally or not accepting connections on port %hu. "
- "Check your remote_port settings in bootstrap.cfg or view the Asset Processor's \"Logs\" tab "
- "for any errors.", connectionSettings.m_assetProcessorPort);
- gEnv = nullptr;
- return AZ::Failure(errorMessage);
- }
- SetEditorCoreEnvironment(gEnv);
- if (gEnv && gEnv->pMovieSystem)
- {
- gEnv->pMovieSystem->EnablePhysicsEvents(m_bSimulationMode);
- }
- CLogFile::AboutSystem();
- REGISTER_CVAR(ed_killmemory_size, -1, VF_DUMPTODISK, "Sets the testing allocation size. -1 for random");
- REGISTER_CVAR(ed_indexfiles, 1, VF_DUMPTODISK, "Index game resource files, 0 - inactive, 1 - active");
- REGISTER_COMMAND("ed_killmemory", KillMemory, VF_NULL, "");
- REGISTER_COMMAND("ed_goto", CmdGotoEditor, VF_CHEAT, "Internal command, used by the 'GOTO' console command\n");
- // The editor needs to handle the quit command differently
- gEnv->pConsole->RemoveCommand("quit");
- REGISTER_COMMAND("quit", CGameEngine::HandleQuitRequest, VF_RESTRICTEDMODE, "Quit/Shutdown the engine");
- CrySystemEventBus::Broadcast(&CrySystemEventBus::Events::OnCryEditorInitialized);
- return AZ::Success();
- }
- bool CGameEngine::InitGame(const char*)
- {
- m_pISystem->ExecuteCommandLine();
- return true;
- }
- void CGameEngine::SetLevelPath(const QString& path)
- {
- QByteArray levelPath;
- levelPath.reserve(AZ_MAX_PATH_LEN);
- levelPath = Path::ToUnixPath(Path::RemoveBackslash(path)).toUtf8();
- m_levelPath = levelPath;
- m_levelName = m_levelPath.mid(m_levelPath.lastIndexOf('/') + 1);
- const char* oldExtension = EditorUtils::LevelFile::GetOldCryFileExtension();
- const char* defaultExtension = EditorUtils::LevelFile::GetDefaultFileExtension();
- // Store off if
- if (QFileInfo(path + oldExtension).exists())
- {
- m_levelExtension = oldExtension;
- }
- else
- {
- m_levelExtension = defaultExtension;
- }
- }
- bool CGameEngine::LoadLevel(
- [[maybe_unused]] bool bDeleteAIGraph,
- [[maybe_unused]] bool bReleaseResources)
- {
- m_bLevelLoaded = false;
- CLogFile::FormatLine("Loading map '%s' into engine...", m_levelPath.toUtf8().data());
- // Switch the current directory back to the Primary CD folder first.
- // The engine might have trouble to find some files when the current
- // directory is wrong
- QDir::setCurrent(GetIEditor()->GetPrimaryCDFolder());
- m_bLevelLoaded = true;
- return true;
- }
- bool CGameEngine::ReloadLevel()
- {
- if (!LoadLevel(false, false))
- {
- return false;
- }
- return true;
- }
- void CGameEngine::SwitchToInGame()
- {
- auto streamer = AZ::Interface<AZ::IO::IStreamer>::Get();
- if (streamer)
- {
- AZStd::binary_semaphore wait;
- AZ::IO::FileRequestPtr flush = streamer->FlushCaches();
- streamer->SetRequestCompleteCallback(flush, [&wait](AZ::IO::FileRequestHandle) { wait.release(); });
- streamer->QueueRequest(flush);
- wait.acquire();
- }
- GetIEditor()->Notify(eNotify_OnBeginGameMode);
- m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(true);
- m_bInGameMode = true;
- m_pISystem->GetIMovieSystem()->Reset(true, false);
- // Transition to runtime entity context.
- AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequestBus::Events::StartPlayInEditor);
- if (!CCryEditApp::instance()->IsInAutotestMode())
- {
- // Constrain and hide the system cursor (important to do this last)
- AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id,
- &AzFramework::InputSystemCursorRequests::SetSystemCursorState,
- AzFramework::SystemCursorState::ConstrainedAndHidden);
- }
- Log("Entered game mode");
- }
- void CGameEngine::SwitchToInEditor()
- {
- // Transition to editor entity context.
- AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequestBus::Events::StopPlayInEditor);
- // Reset movie system
- for (int i = m_pISystem->GetIMovieSystem()->GetNumPlayingSequences(); --i >= 0;)
- {
- m_pISystem->GetIMovieSystem()->GetPlayingSequence(i)->Deactivate();
- }
- m_pISystem->GetIMovieSystem()->Reset(false, false);
- CViewport* pGameViewport = GetIEditor()->GetViewManager()->GetGameViewport();
- m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(m_bSimulationMode);
- m_bInGameMode = false;
- // Out of game in Editor mode.
- if (pGameViewport)
- {
- pGameViewport->SetViewTM(m_playerViewTM);
- }
- GetIEditor()->Notify(eNotify_OnEndGameMode);
- // Unconstrain the system cursor and make it visible (important to do this last)
- AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id,
- &AzFramework::InputSystemCursorRequests::SetSystemCursorState,
- AzFramework::SystemCursorState::UnconstrainedAndVisible);
- Log("Exited game mode");
- }
- void CGameEngine::HandleQuitRequest(IConsoleCmdArgs* /*args*/)
- {
- if (GetIEditor()->GetGameEngine()->IsInGameMode())
- {
- GetIEditor()->GetGameEngine()->RequestSetGameMode(false);
- gEnv->pConsole->ShowConsole(false);
- }
- else
- {
- MainWindow::instance()->window()->close();
- }
- }
- void CGameEngine::RequestSetGameMode(bool inGame)
- {
- m_ePendingGameMode = inGame ? ePGM_SwitchToInGame : ePGM_SwitchToInEditor;
- if (m_ePendingGameMode == ePGM_SwitchToInGame)
- {
- AzToolsFramework::EditorLegacyGameModeNotificationBus::Broadcast(
- &AzToolsFramework::EditorLegacyGameModeNotificationBus::Events::OnStartGameModeRequest);
- }
- else if (m_ePendingGameMode == ePGM_SwitchToInEditor)
- {
- AzToolsFramework::EditorLegacyGameModeNotificationBus::Broadcast(
- &AzToolsFramework::EditorLegacyGameModeNotificationBus::Events::OnStopGameModeRequest);
- }
- }
- void CGameEngine::SetGameMode(bool bInGame)
- {
- if (m_bInGameMode == bInGame)
- {
- return;
- }
- if (!GetIEditor()->GetDocument())
- {
- return;
- }
- GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_GAME_MODE_SWITCH_START, bInGame, 0);
- // Enables engine to know about that.
- gEnv->SetIsEditorGameMode(bInGame);
- // Ignore updates while changing in and out of game mode
- m_bIgnoreUpdates = true;
- // Switching modes will destroy the current AzFramework::EntityConext which may contain
- // data the queued events hold on to, so execute all queued events before switching.
- ExecuteQueuedEvents();
- if (bInGame)
- {
- SwitchToInGame();
- }
- else
- {
- SwitchToInEditor();
- }
- // Enables engine to know about that.
- if (MainWindow::instance())
- {
- AzFramework::InputChannelRequestBus::Broadcast(&AzFramework::InputChannelRequests::ResetState);
- MainWindow::instance()->setFocus();
- }
- GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_EDITOR_GAME_MODE_CHANGED, bInGame, 0);
- m_bIgnoreUpdates = false;
- GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_GAME_MODE_SWITCH_END, bInGame, 0);
- }
- void CGameEngine::SetSimulationMode(bool enabled, bool bOnlyPhysics)
- {
- if (m_bSimulationMode == enabled)
- {
- return;
- }
- m_pISystem->GetIMovieSystem()->EnablePhysicsEvents(enabled);
- if (enabled)
- {
- GetIEditor()->Notify(eNotify_OnBeginSimulationMode);
- }
- else
- {
- GetIEditor()->Notify(eNotify_OnEndSimulationMode);
- }
- m_bSimulationMode = enabled;
- // Enables engine to know about simulation mode.
- gEnv->SetIsEditorSimulationMode(enabled);
- // Execute all queued events before switching modes.
- ExecuteQueuedEvents();
- // Transition back to editor entity context.
- // Symmetry is not critical. It's okay to call this even if we never called StartPlayInEditor
- // (bOnlyPhysics was true when we entered simulation mode).
- AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequestBus::Events::StopPlayInEditor);
- if (m_bSimulationMode && !bOnlyPhysics)
- {
- // Transition to runtime entity context.
- AzToolsFramework::EditorEntityContextRequestBus::Broadcast(&AzToolsFramework::EditorEntityContextRequestBus::Events::StartPlayInEditor);
- }
- AzFramework::InputChannelRequestBus::Broadcast(&AzFramework::InputChannelRequests::ResetState);
- }
- void CGameEngine::SetPlayerViewMatrix(const Matrix34& tm, [[maybe_unused]] bool bEyePos)
- {
- m_playerViewTM = tm;
- }
- void CGameEngine::SyncPlayerPosition(bool bEnable)
- {
- m_bSyncPlayerPosition = bEnable;
- if (m_bSyncPlayerPosition)
- {
- SetPlayerViewMatrix(m_playerViewTM);
- }
- }
- void CGameEngine::SetCurrentMOD(const char* sMod)
- {
- m_MOD = sMod;
- }
- QString CGameEngine::GetCurrentMOD() const
- {
- return m_MOD;
- }
- void CGameEngine::Update()
- {
- if (m_bIgnoreUpdates)
- {
- return;
- }
- switch (m_ePendingGameMode)
- {
- case ePGM_SwitchToInGame:
- {
- SetGameMode(true);
- m_ePendingGameMode = ePGM_NotPending;
- break;
- }
- case ePGM_SwitchToInEditor:
- {
- bool wasInSimulationMode = GetIEditor()->GetGameEngine()->GetSimulationMode();
- if (wasInSimulationMode)
- {
- GetIEditor()->GetGameEngine()->SetSimulationMode(false);
- }
- SetGameMode(false);
- if (wasInSimulationMode)
- {
- GetIEditor()->GetGameEngine()->SetSimulationMode(true);
- }
- m_ePendingGameMode = ePGM_NotPending;
- break;
- }
- }
- AZ::ComponentApplication* componentApplication = nullptr;
- AZ::ComponentApplicationBus::BroadcastResult(componentApplication, &AZ::ComponentApplicationBus::Events::GetApplication);
- if (m_bInGameMode)
- {
- if (gEnv->pSystem)
- {
- gEnv->pSystem->UpdatePreTickBus();
- componentApplication->Tick();
- gEnv->pSystem->UpdatePostTickBus();
- }
- if (CViewport* pRenderViewport = GetIEditor()->GetViewManager()->GetGameViewport())
- {
- pRenderViewport->Update();
- }
- // Check for the Escape key to exit game mode here rather than in Qt,
- // because all Qt events are usually filtered out in game mode in
- // QtEditorApplication_<platform>.cpp nativeEventFilter() to prevent
- // using Editor menu actions and shortcuts that shouldn't trigger while
- // playing the game.
- // When the user opens the console, Qt events will be allowed
- // so the user can interact with limited Editor content like the console.
- const AzFramework::InputChannel* inputChannel = nullptr;
- const AzFramework::InputChannelId channelId(AzFramework::InputDeviceKeyboard::Key::Escape);
- AzFramework::InputChannelRequestBus::EventResult(inputChannel, channelId, &AzFramework::InputChannelRequests::GetInputChannel);
- if(inputChannel && inputChannel->GetState() == AzFramework::InputChannel::State::Began)
- {
- // leave game mode
- RequestSetGameMode(false);
- }
- }
- else
- {
- // [marco] check current sound and vis areas for music etc.
- // but if in game mode, 'cos is already done in the above call to game->update()
- unsigned int updateFlags = ESYSUPDATE_EDITOR;
- GetIEditor()->GetAnimation()->Update();
- GetIEditor()->GetSystem()->UpdatePreTickBus(updateFlags);
- componentApplication->Tick();
- GetIEditor()->GetSystem()->UpdatePostTickBus(updateFlags);
- }
- }
- void CGameEngine::OnEditorNotifyEvent(EEditorNotifyEvent event)
- {
- switch (event)
- {
- case eNotify_OnSplashScreenDestroyed:
- {
- if (m_pSystemUserCallback != nullptr)
- {
- m_pSystemUserCallback->OnSplashScreenDone();
- }
- }
- break;
- }
- }
- void CGameEngine::OnAreaModified([[maybe_unused]] const AABB& modifiedArea)
- {
- }
- void CGameEngine::ExecuteQueuedEvents()
- {
- AZ::Data::AssetBus::ExecuteQueuedEvents();
- AZ::TickBus::ExecuteQueuedEvents();
- AZ::MainThreadRenderRequestBus::ExecuteQueuedEvents();
- }
- #include <moc_GameEngine.cpp>
|