56904d1799
* Generic Cleanup Removals: * Unused cvars,member variables and defines * Windows media center edition support routines * CSystem - removed debug_GetCallStackRaw/GetRootWindowMessageHandler/ UnloadDLL/ShutdownModuleLibraries Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Fix CryMessageBox return values in Windows build Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove named selection group and a few smaller unused functionalities Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove ObjectManager export functionality + 2 deprecated functions Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove object legacy freeze/hide support from ObjectManager Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove ObjectManager duplicate name dection, as well as object renaming Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove ObjectManager serialization and selection callbacks Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * ObjectManager - remove MoveObjects/HitTestObject/EndEditParams and related members/functions Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove a bunch of unused clone related functionality + misc Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * ObjectManager - misc removals Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * ObjectManager - more removals Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove unused object selection/retrieval in ObjectManager and LoadObjects in ObjectLoader Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * CBaseObject - remove unused material layers mask support Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * More CBaseObject cleanups. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * CBaseObject - remove SubObj functions and IMouseCreateCallback Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove unused procedural floor management, helper scale and tags. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * CBaseObject - remove more unused methods. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Removals in multiple places. CBaseObject - unused `OBJTYPE_DUMMY` flag removed, member `IsSameClass` CObjectArchive removed unused methods/members CObjectManager removed unused `Update` method Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * More removals IDisplayViewport - HitTestLine/GetGridStep/setHitcontext/ GetConstructionPlane Unused Cry_Matrix44 template specializations. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * O3DE.exe Project-Centric "Open Editor" fix (#5852) * The O3DE.exe Open Editor button now attempts to open the Editor in the build directory of the project being opened. If their is no Editor within the build directory of the Project, it uses the Editor.exe in the current O3DE.exe executable directory if it exists Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Engine .gitignore now ignores the build directory if placed in the AutomatedTesting project Previously it was just ignoring a `[Bb]uild` directory if it was directly within the engine root. This change matches the behavior of the project templates. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Renamed the ProjectUtils GetEditorDirectory function to GetEditorExecutablePath Added a platform specific implementation for retrieving the path to the Editor executable in the GetEditorExectuablePath function. It first attempts to locate the Editor via checking the project build directory for an Editor executable before falling back to checking the binary directory of the currently running O3DE executable. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Correct the MacOS GetEditorExecutablePath to return the Editor path Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Adding missing C++20 std::erase implementations (#5735) There were already implementations for std::erase_if. This adds the counterpart AZStd::erase versions resolves #5734 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * More removals and refactors `ShowMessage` and `CryMessageBox` return void now Simplify code in `CSystem::WarningV` Remove unused `CryGetTicksPerSec` Remove unused WinBase functionality Replace `nanosleep` call in WinBase with `std::this_thread::sleep_for` Remove unused Win32Wrapper routines Remove unused IFunctorBase.h and IEntityObjectListener.h Fix VectorAndArray.cpp compilation Use QMessageBox instead of CryMessageBox in the editor. Remove empty ArchiveVars platform specific files Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Fix test code. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove an unused function Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * CBaseObject and undo description removals. Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * A bunch of removals * Remove IRenderNode * Remove editor's KDTree * Remove StatObjBus, InstanceStatObjEventBus::ReleaseData is redundant ( same functionality in the only available handler is triggered by `OnCryEditorCloseScene`) * Remove CExportManager::AddStatObj/AddMeshes/AddMesh, IExportManager::ExportSingleStatObj * Remove CIconManager/IIconManager::GetObject * Remove CBaseObject::IntersectRayMesh * Remove IIndexedMesh and related structs. * Unused IUndoObject::GetDescription and all derived implementations. * Unused CUndoBaseLibrary/CUndoBaseLibraryManager * Unused Matrix34_tpl typedefs * Legacy Xml classes cleanup Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * Remove unused `Vec3ToVector3D` helper Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> * fix - remove unused static variable Signed-off-by: nemerle <96597+nemerle@users.noreply.github.com> Co-authored-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
1489 lines
54 KiB
C++
1489 lines
54 KiB
C++
/*
|
|
* 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 "CrySystem_precompiled.h"
|
|
#include "System.h"
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM) || defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS)
|
|
#undef AZ_RESTRICTED_SECTION
|
|
#define SYSTEMINIT_CPP_SECTION_2 2
|
|
#define SYSTEMINIT_CPP_SECTION_3 3
|
|
#define SYSTEMINIT_CPP_SECTION_4 4
|
|
#define SYSTEMINIT_CPP_SECTION_5 5
|
|
#define SYSTEMINIT_CPP_SECTION_6 6
|
|
#define SYSTEMINIT_CPP_SECTION_7 7
|
|
#define SYSTEMINIT_CPP_SECTION_8 8
|
|
#define SYSTEMINIT_CPP_SECTION_9 9
|
|
#define SYSTEMINIT_CPP_SECTION_10 10
|
|
#define SYSTEMINIT_CPP_SECTION_11 11
|
|
#define SYSTEMINIT_CPP_SECTION_12 12
|
|
#define SYSTEMINIT_CPP_SECTION_13 13
|
|
#define SYSTEMINIT_CPP_SECTION_14 14
|
|
#define SYSTEMINIT_CPP_SECTION_15 15
|
|
#define SYSTEMINIT_CPP_SECTION_16 16
|
|
#define SYSTEMINIT_CPP_SECTION_17 17
|
|
#endif
|
|
|
|
#include "CryPath.h"
|
|
|
|
#include <AzFramework/Input/Devices/Mouse/InputDeviceMouse.h>
|
|
#include <AzFramework/IO/LocalFileIO.h>
|
|
|
|
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
|
|
#include <AzCore/IO/Streamer/Streamer.h>
|
|
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
|
#include <AzCore/Component/ComponentApplicationBus.h>
|
|
#include <AzFramework/API/ApplicationAPI.h>
|
|
#include <AzFramework/StringFunc/StringFunc.h>
|
|
#include <AzFramework/Asset/AssetProcessorMessages.h>
|
|
#include <AzFramework/Asset/AssetSystemBus.h>
|
|
#include <AzFramework/Asset/AssetCatalogBus.h>
|
|
#include <AzFramework/API/ApplicationAPI.h>
|
|
#include "AZCoreLogSink.h"
|
|
#include <AzCore/Math/MathUtils.h>
|
|
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
|
#include <AzFramework/Archive/INestedArchive.h>
|
|
#include <AzFramework/Archive/ArchiveFileIO.h>
|
|
|
|
#include <LoadScreenBus.h>
|
|
#include <LyShine/Bus/UiSystemBus.h>
|
|
#include <AzFramework/Logging/MissingAssetLogger.h>
|
|
#include <AzFramework/Platform/PlatformDefaults.h>
|
|
#include <AzCore/Interface/Interface.h>
|
|
#include <AzCore/Utils/Utils.h>
|
|
|
|
#if defined(APPLE) || defined(LINUX)
|
|
#include <dlfcn.h>
|
|
#include <cstdlib>
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include "windows.h"
|
|
#include <float.h>
|
|
|
|
#endif //WIN32
|
|
|
|
#include <IRenderer.h>
|
|
#include <AzCore/IO/FileIO.h>
|
|
#include <IMovieSystem.h>
|
|
#include <ILog.h>
|
|
#include <IAudioSystem.h>
|
|
#include <ICmdLine.h>
|
|
#include <IProcess.h>
|
|
#include <LyShine/ILyShine.h>
|
|
|
|
#include <AzFramework/Archive/Archive.h>
|
|
#include "XConsole.h"
|
|
#include "Log.h"
|
|
#include "XML/xml.h"
|
|
#include "LocalizedStringManager.h"
|
|
#include "SystemEventDispatcher.h"
|
|
#include "LevelSystem/LevelSystem.h"
|
|
#include "LevelSystem/SpawnableLevelSystem.h"
|
|
#include <CrySystemBus.h>
|
|
#include <AzCore/Jobs/JobFunction.h>
|
|
#include <AzCore/Jobs/JobManagerBus.h>
|
|
|
|
#if defined(ANDROID)
|
|
#include <AzCore/Android/Utils.h>
|
|
#endif
|
|
|
|
#if defined(EXTERNAL_CRASH_REPORTING)
|
|
#include <CrashHandler.h>
|
|
#endif
|
|
|
|
// select the asset processor based on cvars and defines.
|
|
// uncomment the following and edit the path where it is instantiated if you'd like to use the test file client
|
|
//#define USE_TEST_FILE_CLIENT
|
|
|
|
#if defined(REMOTE_ASSET_PROCESSOR)
|
|
// Over here, we'd put the header to the Remote Asset Processor interface (as opposed to the Local built in version below)
|
|
# include <AzFramework/Network/AssetProcessorConnection.h>
|
|
#endif
|
|
|
|
#ifdef WIN32
|
|
extern LONG WINAPI CryEngineExceptionFilterWER(struct _EXCEPTION_POINTERS* pExceptionPointers);
|
|
#endif
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_14
|
|
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
|
#endif
|
|
|
|
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
|
|
|
|
#include <execinfo.h>
|
|
#include <signal.h>
|
|
void CryEngineSignalHandler(int signal)
|
|
{
|
|
char resolvedPath[_MAX_PATH];
|
|
|
|
// it is assumed that @log@ points at the appropriate place (so for apple, to the user profile dir)
|
|
if (AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath("@log@/crash.log", resolvedPath, _MAX_PATH))
|
|
{
|
|
fprintf(stderr, "Crash Signal Handler - logged to %s\n", resolvedPath);
|
|
FILE* file = fopen(resolvedPath, "a");
|
|
if (file)
|
|
{
|
|
char sTime[128];
|
|
time_t ltime;
|
|
time(<ime);
|
|
struct tm* today = localtime(<ime);
|
|
strftime(sTime, 40, "<%Y-%m-%d %H:%M:%S> ", today);
|
|
fprintf(file, "%s: Error: signal %s:\n", sTime, strsignal(signal));
|
|
fflush(file);
|
|
void* array[100];
|
|
int s = backtrace(array, 100);
|
|
backtrace_symbols_fd(array, s, fileno(file));
|
|
fclose(file);
|
|
CryLogAlways("Successfully recorded crash file: '%s'", resolvedPath);
|
|
abort();
|
|
}
|
|
}
|
|
|
|
CryLogAlways("Could not record crash file...");
|
|
abort();
|
|
}
|
|
|
|
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define DEFAULT_LOG_FILENAME "@log@/Log.txt"
|
|
|
|
#define CRYENGINE_ENGINE_FOLDER "Engine"
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
#define CRYENGINE_DEFAULT_LOCALIZATION_LANG "en-US"
|
|
|
|
#define LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME "Libs/Localization/localization.xml"
|
|
|
|
#define AZ_TRACE_SYSTEM_WINDOW AZ::Debug::Trace::GetDefaultSystemWindow()
|
|
|
|
#ifdef WIN32
|
|
extern HMODULE gDLLHandle;
|
|
#endif
|
|
|
|
|
|
//static int g_sysSpecChanged = false;
|
|
|
|
struct SCVarsClientConfigSink
|
|
: public ILoadConfigurationEntrySink
|
|
{
|
|
virtual void OnLoadConfigurationEntry(const char* szKey, const char* szValue, [[maybe_unused]] const char* szGroup)
|
|
{
|
|
gEnv->pConsole->SetClientDataProbeString(szKey, szValue);
|
|
}
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
static inline void InlineInitializationProcessing([[maybe_unused]] const char* sDescription)
|
|
{
|
|
if (gEnv->pLog)
|
|
{
|
|
gEnv->pLog->UpdateLoadingScreen(0);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
AZ_PUSH_DISABLE_WARNING(4723, "-Wunknown-warning-option") // potential divide by 0 (needs to wrap the function)
|
|
static void CmdCrashTest(IConsoleCmdArgs* pArgs)
|
|
{
|
|
assert(pArgs);
|
|
|
|
if (pArgs->GetArgCount() == 2)
|
|
{
|
|
//This method intentionally crashes, a lot.
|
|
|
|
int crashType = atoi(pArgs->GetArg(1));
|
|
switch (crashType)
|
|
{
|
|
case 1:
|
|
{
|
|
int* p = 0;
|
|
*p = 0xABCD;
|
|
}
|
|
break;
|
|
case 2:
|
|
{
|
|
float a = 1.0f;
|
|
memset(&a, 0, sizeof(a));
|
|
[[maybe_unused]] float* b = &a;
|
|
[[maybe_unused]] float c = 3;
|
|
CryLog("%f", (c / *b));
|
|
}
|
|
break;
|
|
case 3:
|
|
while (true)
|
|
{
|
|
new char[10240];
|
|
}
|
|
break;
|
|
case 4:
|
|
CryFatalError("sys_crashtest 4");
|
|
break;
|
|
case 5:
|
|
while (true)
|
|
{
|
|
new char[128]; //testing the crash handler an exception in the cry memory allocation occurred
|
|
}
|
|
case 6:
|
|
{
|
|
AZ_Assert(false, "Testing assert for testing crashes");
|
|
}
|
|
break;
|
|
case 7:
|
|
__debugbreak();
|
|
break;
|
|
case 8:
|
|
CrySleep(1000 * 60 * 10);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
AZ_POP_DISABLE_WARNING
|
|
|
|
static ESystemConfigPlatform GetDevicePlatform()
|
|
{
|
|
#if defined(AZ_PLATFORM_WINDOWS) || defined(AZ_PLATFORM_LINUX)
|
|
return CONFIG_PC;
|
|
#define AZ_RESTRICTED_SECTION_IMPLEMENTED
|
|
#elif defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_2
|
|
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
|
#endif
|
|
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
|
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
|
#elif defined(AZ_PLATFORM_ANDROID)
|
|
return CONFIG_ANDROID;
|
|
#elif defined(AZ_PLATFORM_IOS)
|
|
return CONFIG_IOS;
|
|
#elif defined(AZ_PLATFORM_MAC)
|
|
return CONFIG_OSX_METAL;
|
|
#else
|
|
AZ_Assert(false, "Platform not supported");
|
|
return CONFIG_INVALID_PLATFORM;
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
bool CSystem::InitConsole()
|
|
{
|
|
if (m_env.pConsole)
|
|
{
|
|
m_env.pConsole->Init(this);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// attaches the given variable to the given container;
|
|
// recreates the variable if necessary
|
|
ICVar* CSystem::attachVariable (const char* szVarName, int* pContainer, const char* szComment, int dwFlags)
|
|
{
|
|
IConsole* pConsole = GetIConsole();
|
|
|
|
ICVar* pOldVar = pConsole->GetCVar (szVarName);
|
|
int nDefault = 0;
|
|
if (pOldVar)
|
|
{
|
|
nDefault = pOldVar->GetIVal();
|
|
pConsole->UnregisterVariable(szVarName, true);
|
|
}
|
|
|
|
// NOTE: maybe we should preserve the actual value of the variable across the registration,
|
|
// because of the strange architecture of IConsole that converts int->float->int
|
|
|
|
REGISTER_CVAR2(szVarName, pContainer, *pContainer, dwFlags, szComment);
|
|
|
|
ICVar* pVar = pConsole->GetCVar(szVarName);
|
|
|
|
#ifdef _DEBUG
|
|
// test if the variable really has this container
|
|
assert (*pContainer == pVar->GetIVal());
|
|
++*pContainer;
|
|
assert (*pContainer == pVar->GetIVal());
|
|
--*pContainer;
|
|
#endif
|
|
|
|
if (pOldVar)
|
|
{
|
|
// carry on the default value from the old variable anyway
|
|
pVar->Set(nDefault);
|
|
}
|
|
return pVar;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
bool CSystem::InitFileSystem()
|
|
{
|
|
using namespace AzFramework::AssetSystem;
|
|
|
|
if (m_pUserCallback)
|
|
{
|
|
m_pUserCallback->OnInitProgress("Initializing File System...");
|
|
}
|
|
|
|
m_env.pCryPak = AZ::Interface<AZ::IO::IArchive>::Get();
|
|
m_env.pFileIO = AZ::IO::FileIOBase::GetInstance();
|
|
AZ_Assert(m_env.pCryPak, "CryPak has not been initialized on AZ::Interface");
|
|
AZ_Assert(m_env.pFileIO, "FileIOBase has not been initialized");
|
|
|
|
if (m_bEditor)
|
|
{
|
|
m_env.pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_EngineStartup);
|
|
}
|
|
|
|
// Now that file systems are init, we will clear any events that have arrived
|
|
// during file system init, so that systems do not reload assets that were already compiled in the
|
|
// critical compilation section.
|
|
|
|
AzFramework::LegacyAssetEventBus::ClearQueuedEvents();
|
|
|
|
//we are good to go
|
|
return true;
|
|
}
|
|
|
|
|
|
void CSystem::ShutdownFileSystem()
|
|
{
|
|
m_env.pFileIO = nullptr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
bool CSystem::InitFileSystem_LoadEngineFolders(const SSystemInitParams&)
|
|
{
|
|
LoadConfiguration(m_systemConfigName.c_str());
|
|
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Loading system configuration from %s...", m_systemConfigName.c_str());
|
|
|
|
#if defined(AZ_PLATFORM_ANDROID)
|
|
AZ::Android::Utils::SetLoadFilesToMemory(m_sys_load_files_to_memory->GetString());
|
|
#endif
|
|
|
|
GetISystem()->SetConfigPlatform(GetDevicePlatform());
|
|
|
|
auto projectPath = AZ::Utils::GetProjectPath();
|
|
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Path: %s\n", projectPath.empty() ? "None specified" : projectPath.c_str());
|
|
|
|
auto projectName = AZ::Utils::GetProjectName();
|
|
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Project Name: %s\n", projectName.empty() ? "None specified" : projectName.c_str());
|
|
|
|
OpenPlatformPaks();
|
|
|
|
// Load game-specific folder.
|
|
LoadConfiguration("game.cfg");
|
|
// Load the client/sever-specific configuration
|
|
static const char* g_additionalConfig = gEnv->IsDedicated() ? "server_cfg" : "client_cfg";
|
|
LoadConfiguration(g_additionalConfig, nullptr, false);
|
|
|
|
// We do not use CVar groups on the consoles
|
|
AddCVarGroupDirectory("Config/CVarGroups");
|
|
|
|
return (true);
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
bool CSystem::InitAudioSystem(const SSystemInitParams& initParams)
|
|
{
|
|
if (!Audio::Gem::AudioSystemGemRequestBus::HasHandlers())
|
|
{
|
|
// AudioSystem Gem has not been enabled for this project.
|
|
// This should not generate an error, but calling scope will warn.
|
|
return false;
|
|
}
|
|
|
|
bool useRealAudioSystem = false;
|
|
if (!initParams.bPreview
|
|
&& !m_bDedicatedServer
|
|
&& m_sys_audio_disable->GetIVal() == 0)
|
|
{
|
|
useRealAudioSystem = true;
|
|
}
|
|
|
|
bool result = false;
|
|
if (useRealAudioSystem)
|
|
{
|
|
Audio::Gem::AudioSystemGemRequestBus::BroadcastResult(result, &Audio::Gem::AudioSystemGemRequestBus::Events::Initialize, &initParams);
|
|
}
|
|
else
|
|
{
|
|
Audio::Gem::AudioSystemGemRequestBus::BroadcastResult(result, &Audio::Gem::AudioSystemGemRequestBus::Events::Initialize, nullptr);
|
|
}
|
|
|
|
if (result)
|
|
{
|
|
AZ_Assert(Audio::AudioSystemRequestBus::HasHandlers(),
|
|
"Initialization of the Audio System succeeded, but the Audio System EBus is not connected!\n");
|
|
}
|
|
else
|
|
{
|
|
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, result, "The Audio System did not initialize correctly!\n");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::InitLocalization()
|
|
{
|
|
// Set the localization folder
|
|
ICVar* pCVar = m_env.pConsole != 0 ? m_env.pConsole->GetCVar("sys_localization_folder") : 0;
|
|
if (pCVar)
|
|
{
|
|
static_cast<AZ::IO::Archive* const>(m_env.pCryPak)->SetLocalizationFolder(g_cvars.sys_localization_folder->GetString());
|
|
}
|
|
|
|
// Removed line that assigned language based on a #define
|
|
|
|
if (m_pLocalizationManager == nullptr)
|
|
{
|
|
m_pLocalizationManager = new CLocalizedStringsManager(this);
|
|
}
|
|
|
|
// Platform-specific implementation of getting the system language
|
|
ILocalizationManager::EPlatformIndependentLanguageID languageID = m_pLocalizationManager->GetSystemLanguage();
|
|
if (!m_pLocalizationManager->IsLanguageSupported(languageID))
|
|
{
|
|
languageID = ILocalizationManager::EPlatformIndependentLanguageID::ePILID_English_US;
|
|
}
|
|
|
|
AZStd::string language = m_pLocalizationManager->LangNameFromPILID(languageID);
|
|
m_pLocalizationManager->SetLanguage(language.c_str());
|
|
if (m_pLocalizationManager->GetLocalizationFormat() == 1)
|
|
{
|
|
AZStd::string translationsListXML = LOCALIZATION_TRANSLATIONS_LIST_FILE_NAME;
|
|
m_pLocalizationManager->InitLocalizationData(translationsListXML.c_str());
|
|
|
|
m_pLocalizationManager->LoadAllLocalizationData();
|
|
}
|
|
else
|
|
{
|
|
// if the language value cannot be found, let's default to the english pak
|
|
OpenLanguagePak(language.c_str());
|
|
}
|
|
|
|
if (auto console = AZ::Interface<AZ::IConsole>::Get(); console != nullptr)
|
|
{
|
|
AZ::CVarFixedString languageAudio;
|
|
console->GetCvarValue("g_languageAudio", languageAudio);
|
|
if (languageAudio.empty())
|
|
{
|
|
console->PerformCommand(AZStd::string::format("g_languageAudio %s", language.c_str()).c_str());
|
|
}
|
|
else
|
|
{
|
|
language.assign(languageAudio.data(), languageAudio.size());
|
|
}
|
|
}
|
|
OpenLanguageAudioPak(language.c_str());
|
|
}
|
|
|
|
void CSystem::OpenPlatformPaks()
|
|
{
|
|
static bool bPlatformPaksLoaded = false;
|
|
if (bPlatformPaksLoaded)
|
|
{
|
|
return;
|
|
}
|
|
bPlatformPaksLoaded = true;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Open engine packs
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_15
|
|
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
|
#endif
|
|
|
|
#ifdef AZ_PLATFORM_ANDROID
|
|
const char* const assetsDir = "@products@";
|
|
// Load Android Obb files if available
|
|
const char* obbStorage = AZ::Android::Utils::GetObbStoragePath();
|
|
AZStd::string mainObbPath = AZStd::move(AZStd::string::format("%s/%s", obbStorage, AZ::Android::Utils::GetObbFileName(true)));
|
|
AZStd::string patchObbPath = AZStd::move(AZStd::string::format("%s/%s", obbStorage, AZ::Android::Utils::GetObbFileName(false)));
|
|
m_env.pCryPak->OpenPack(assetsDir, mainObbPath.c_str());
|
|
m_env.pCryPak->OpenPack(assetsDir, patchObbPath.c_str());
|
|
#endif //AZ_PLATFORM_ANDROID
|
|
|
|
InlineInitializationProcessing("CSystem::OpenPlatformPaks OpenPacks( Engine... )");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::OpenLanguagePak(const char* sLanguage)
|
|
{
|
|
// Don't attempt to open a language PAK file if the game doesn't have a
|
|
// loc folder configured.
|
|
bool projUsesLocalization = false;
|
|
LocalizationManagerRequestBus::BroadcastResult(projUsesLocalization, &LocalizationManagerRequestBus::Events::ProjectUsesLocalization);
|
|
if (!projUsesLocalization)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Initialize languages.
|
|
|
|
// Omit the trailing slash!
|
|
AZStd::string sLocalizationFolder = PathUtil::GetLocalizationFolder();
|
|
|
|
// load xml pak with full filenames to perform wildcard searches.
|
|
AZStd::string sLocalizedPath;
|
|
GetLocalizedPath(sLanguage, sLocalizedPath);
|
|
if (!m_env.pCryPak->OpenPacks({ sLocalizationFolder.c_str(), sLocalizationFolder.size() }, { sLocalizedPath.c_str(), sLocalizedPath.size() }, 0))
|
|
{
|
|
// make sure the localized language is found - not really necessary, for TC
|
|
AZ_Printf("Localization", "Localized language content(%s) not available or modified from the original installation.", sLanguage);
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::OpenLanguageAudioPak([[maybe_unused]] const char* sLanguage)
|
|
{
|
|
// Don't attempt to open a language PAK file if the game doesn't have a
|
|
// loc folder configured.
|
|
bool projUsesLocalization = false;
|
|
LocalizationManagerRequestBus::BroadcastResult(projUsesLocalization, &LocalizationManagerRequestBus::Events::ProjectUsesLocalization);
|
|
if (!projUsesLocalization)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Initialize languages.
|
|
|
|
// Omit the trailing slash!
|
|
AZStd::string sLocalizationFolder(AZStd::string().assign(PathUtil::GetLocalizationFolder(), 0, PathUtil::GetLocalizationFolder().size() - 1));
|
|
|
|
if (!AZ::StringFunc::Equal(sLocalizationFolder, "Languages", false))
|
|
{
|
|
sLocalizationFolder = "@products@";
|
|
}
|
|
|
|
// load localized pak with crc32 filenames on consoles to save memory.
|
|
AZStd::string sLocalizedPath = "loc.pak";
|
|
|
|
if (!m_env.pCryPak->OpenPacks(sLocalizationFolder.c_str(), sLocalizedPath.c_str()))
|
|
{
|
|
// make sure the localized language is found - not really necessary, for TC
|
|
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Localized language content(%s) not available or modified from the original installation.", sLanguage);
|
|
}
|
|
}
|
|
|
|
|
|
AZStd::string GetUniqueLogFileName(AZStd::string logFileName)
|
|
{
|
|
AZStd::string logFileNamePrefix = logFileName;
|
|
if ((logFileNamePrefix[0] != '@') && (AzFramework::StringFunc::Path::IsRelative(logFileNamePrefix.c_str())))
|
|
{
|
|
logFileNamePrefix = "@log@/";
|
|
logFileNamePrefix += logFileName;
|
|
}
|
|
|
|
char resolvedLogFilePathBuffer[AZ_MAX_PATH_LEN] = { 0 };
|
|
AZ::IO::FileIOBase::GetDirectInstance()->ResolvePath(logFileNamePrefix.c_str(), resolvedLogFilePathBuffer, AZ_MAX_PATH_LEN);
|
|
|
|
int instance = gEnv->pSystem->GetApplicationLogInstance(resolvedLogFilePathBuffer);
|
|
|
|
if (instance == 0)
|
|
{
|
|
return logFileNamePrefix;
|
|
}
|
|
|
|
AZStd::string logFileExtension;
|
|
size_t extensionIndex = logFileName.find_last_of('.');
|
|
if (extensionIndex != AZStd::string::npos)
|
|
{
|
|
logFileExtension = logFileName.substr(extensionIndex, logFileName.length() - extensionIndex);
|
|
logFileNamePrefix = logFileName.substr(0, extensionIndex);
|
|
}
|
|
|
|
logFileName = AZStd::string::format("%s(%d)%s", logFileNamePrefix.c_str(), instance, logFileExtension.c_str()).c_str();
|
|
|
|
return logFileName;
|
|
}
|
|
|
|
class AzConsoleToCryConsoleBinder final
|
|
{
|
|
public:
|
|
static void OnInvoke(IConsoleCmdArgs* args)
|
|
{
|
|
std::string command = args->GetCommandLine();
|
|
const size_t delim = command.find_first_of('=');
|
|
if (delim != std::string::npos)
|
|
{
|
|
// All Cry executed cfg files will come in through this pathway in addition to regular commands
|
|
// We strip out the = sign at this layer to maintain compatibility with cvars that use the '=' as a separator
|
|
// Swap the '=' character for a space
|
|
command[delim] = ' ';
|
|
}
|
|
|
|
AZ::Interface<AZ::IConsole>::Get()->PerformCommand(command.c_str(), AZ::ConsoleSilentMode::Silent, AZ::ConsoleInvokedFrom::CryBinding);
|
|
}
|
|
|
|
static void OnVarChanged(ICVar* cvar)
|
|
{
|
|
AZ::CVarFixedString command = AZ::CVarFixedString::format("%s %s", cvar->GetName(), cvar->GetString());
|
|
AZ::Interface<AZ::IConsole>::Get()->PerformCommand(command.c_str(), AZ::ConsoleSilentMode::Silent, AZ::ConsoleInvokedFrom::CryBinding);
|
|
}
|
|
|
|
static void Visit(AZ::ConsoleFunctorBase* functor)
|
|
{
|
|
if (gEnv->pConsole == nullptr)
|
|
{
|
|
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Cry console was NULL while attempting to register Az CVars and CFuncs.\n");
|
|
return;
|
|
}
|
|
|
|
int32_t cryFlags = VF_NET_SYNCED;
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::DontReplicate) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags = VF_NULL;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::ServerOnly) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_DEDI_ONLY;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::ReadOnly) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_READONLY;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::IsCheat) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_CHEAT;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::IsInvisible) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_INVISIBLE;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::IsDeprecated) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_DEPRECATED;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::NeedsReload) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_REQUIRE_APP_RESTART;
|
|
}
|
|
if ((functor->GetFlags() & AZ::ConsoleFunctorFlags::AllowClientSet) != AZ::ConsoleFunctorFlags::Null)
|
|
{
|
|
cryFlags |= VF_DEV_ONLY;
|
|
}
|
|
|
|
gEnv->pConsole->RemoveCommand(functor->GetName());
|
|
if (functor->GetTypeId() != AZ::TypeId::CreateNull())
|
|
{
|
|
AZ::CVarFixedString value;
|
|
functor->GetValue(value);
|
|
gEnv->pConsole->RegisterString(functor->GetName(), value.c_str(), cryFlags, functor->GetDesc(), AzConsoleToCryConsoleBinder::OnVarChanged);
|
|
}
|
|
else
|
|
{
|
|
gEnv->pConsole->AddCommand(functor->GetName(), AzConsoleToCryConsoleBinder::OnInvoke, cryFlags, functor->GetDesc());
|
|
}
|
|
}
|
|
|
|
using CommandRegisteredHandler = AZ::IConsole::ConsoleCommandRegisteredEvent::Handler;
|
|
static inline CommandRegisteredHandler s_commandRegisteredHandler = CommandRegisteredHandler([](AZ::ConsoleFunctorBase* functor) { Visit(functor); });
|
|
};
|
|
|
|
// System initialization
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
// INIT
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
bool CSystem::Init(const SSystemInitParams& startupParams)
|
|
{
|
|
#if AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
|
|
signal(SIGSEGV, CryEngineSignalHandler);
|
|
signal(SIGTRAP, CryEngineSignalHandler);
|
|
signal(SIGILL, CryEngineSignalHandler);
|
|
#endif // AZ_TRAIT_USE_CRY_SIGNAL_HANDLER
|
|
|
|
// Temporary Fix for an issue accessing gEnv from this object instance. The gEnv is not resolving to the
|
|
// global gEnv, instead its resolving an some uninitialized gEnv elsewhere (NULL). Since gEnv is
|
|
// initialized to this instance's SSystemGlobalEnvironment (m_env), we will force set it again here
|
|
// to m_env
|
|
if (!gEnv)
|
|
{
|
|
gEnv = &m_env;
|
|
}
|
|
|
|
SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_INIT);
|
|
gEnv->mMainThreadId = GetCurrentThreadId(); //Set this ASAP on startup
|
|
|
|
InlineInitializationProcessing("CSystem::Init start");
|
|
|
|
m_env.bNoAssertDialog = false;
|
|
|
|
m_bNoCrashDialog = gEnv->IsDedicated();
|
|
|
|
if (startupParams.bUnattendedMode)
|
|
{
|
|
m_bNoCrashDialog = true;
|
|
m_env.bNoAssertDialog = true; //this also suppresses CryMessageBox
|
|
g_cvars.sys_no_crash_dialog = true;
|
|
}
|
|
|
|
#if defined(AZ_PLATFORM_LINUX)
|
|
// Linux is all console for now and so no room for dialog boxes!
|
|
m_env.bNoAssertDialog = true;
|
|
#endif
|
|
|
|
m_pCmdLine = new CCmdLine(startupParams.szSystemCmdLine);
|
|
|
|
AZCoreLogSink::Connect();
|
|
|
|
// Registers all AZ Console Variables functors specified within CrySystem
|
|
if (auto azConsole = AZ::Interface<AZ::IConsole>::Get(); azConsole)
|
|
{
|
|
azConsole->LinkDeferredFunctors(AZ::ConsoleFunctorBase::GetDeferredHead());
|
|
}
|
|
|
|
if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry)
|
|
{
|
|
AZ::SettingsRegistryInterface::FixedValueString assetPlatform;
|
|
if (!AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, assetPlatform,
|
|
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "assets"))
|
|
{
|
|
assetPlatform = AzFramework::OSPlatformToDefaultAssetPlatform(AZ_TRAIT_OS_PLATFORM_CODENAME);
|
|
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, R"(A valid asset platform is missing in "%s/assets" key in the SettingsRegistry.)""\n"
|
|
R"(This typically done by setting the "assets" field within a .setreg file)""\n"
|
|
R"(A fallback of %s will be used.)",
|
|
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
|
|
assetPlatform.c_str());
|
|
}
|
|
|
|
m_systemConfigName = "system_" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_";
|
|
m_systemConfigName += assetPlatform.c_str();
|
|
m_systemConfigName += ".cfg";
|
|
}
|
|
|
|
#if defined(WIN32) || defined(WIN64)
|
|
// check OS version - we only want to run on XP or higher - talk to Martin Mittring if you want to change this
|
|
{
|
|
OSVERSIONINFO osvi;
|
|
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
AZ_PUSH_DISABLE_WARNING(4996, "-Wunknown-warning-option")
|
|
GetVersionExW(&osvi);
|
|
AZ_POP_DISABLE_WARNING
|
|
|
|
bool bIsWindowsXPorLater = osvi.dwMajorVersion > 5 || (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion >= 1);
|
|
|
|
if (!bIsWindowsXPorLater)
|
|
{
|
|
AZ_Error(AZ_TRACE_SYSTEM_WINDOW, false, "Open 3D Engine requires an OS version of Windows XP or later.");
|
|
return false;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Get file version information.
|
|
QueryVersionInfo();
|
|
DetectGameFolderAccessRights();
|
|
|
|
m_bEditor = startupParams.bEditor;
|
|
m_bPreviewMode = startupParams.bPreview;
|
|
m_bTestMode = startupParams.bTestMode;
|
|
m_pUserCallback = startupParams.pUserCallback;
|
|
|
|
m_bDedicatedServer = startupParams.bDedicatedServer;
|
|
m_currentLanguageAudio = "";
|
|
|
|
#if !defined(CONSOLE)
|
|
m_env.SetIsEditor(m_bEditor);
|
|
m_env.SetIsEditorGameMode(false);
|
|
m_env.SetIsEditorSimulationMode(false);
|
|
#endif
|
|
|
|
m_env.SetToolMode(startupParams.bToolMode);
|
|
|
|
if (m_bEditor)
|
|
{
|
|
m_bInDevMode = true;
|
|
}
|
|
|
|
if (!gEnv->IsDedicated())
|
|
{
|
|
const ICmdLineArg* crashdialog = m_pCmdLine->FindArg(eCLAT_Post, "sys_no_crash_dialog");
|
|
if (crashdialog)
|
|
{
|
|
m_bNoCrashDialog = true;
|
|
}
|
|
}
|
|
|
|
#if !defined(_RELEASE)
|
|
if (!m_bDedicatedServer)
|
|
{
|
|
const ICmdLineArg* dedicated = m_pCmdLine->FindArg(eCLAT_Pre, "dedicated");
|
|
if (dedicated)
|
|
{
|
|
m_bDedicatedServer = true;
|
|
}
|
|
}
|
|
#endif // !defined(_RELEASE)
|
|
|
|
#if !defined(CONSOLE)
|
|
gEnv->SetIsDedicated(m_bDedicatedServer);
|
|
#endif
|
|
|
|
{
|
|
EBUS_EVENT(CrySystemEventBus, OnCrySystemPreInitialize, *this, startupParams);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// File system, must be very early
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (!InitFileSystem())
|
|
{
|
|
return false;
|
|
}
|
|
//////////////////////////////////////////////////////////////////////////
|
|
InlineInitializationProcessing("CSystem::Init InitFileSystem");
|
|
|
|
m_missingAssetLogger = AZStd::make_unique<AzFramework::MissingAssetLogger>();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Logging is only available after file system initialization.
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (!startupParams.pLog)
|
|
{
|
|
m_env.pLog = new CLog(this);
|
|
if (startupParams.pLogCallback)
|
|
{
|
|
m_env.pLog->AddCallback(startupParams.pLogCallback);
|
|
}
|
|
|
|
const ICmdLineArg* logfile = m_pCmdLine->FindArg(eCLAT_Pre, "logfile"); //see if the user specified a log name, if so use it
|
|
if (logfile && strlen(logfile->GetValue()) > 0)
|
|
{
|
|
m_env.pLog->SetFileName(logfile->GetValue(), startupParams.autoBackupLogs);
|
|
}
|
|
else if (startupParams.sLogFileName) //otherwise see if the startup params has a log file name, if so use it
|
|
{
|
|
const AZStd::string sUniqueLogFileName = GetUniqueLogFileName(startupParams.sLogFileName);
|
|
m_env.pLog->SetFileName(sUniqueLogFileName.c_str(), startupParams.autoBackupLogs);
|
|
}
|
|
else//use the default log name
|
|
{
|
|
m_env.pLog->SetFileName(DEFAULT_LOG_FILENAME, startupParams.autoBackupLogs);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_env.pLog = startupParams.pLog;
|
|
}
|
|
|
|
// The log backup system expects the version number to be the first line of the log
|
|
// so we log this immediately after setting the log filename
|
|
LogVersion();
|
|
|
|
bool devModeEnable = true;
|
|
|
|
#if defined(_RELEASE)
|
|
// disable devmode by default in release builds outside the editor
|
|
devModeEnable = m_bEditor;
|
|
#endif
|
|
|
|
// disable devmode in launcher if someone really wants to (even in non release builds)
|
|
if (!m_bEditor && m_pCmdLine->FindArg(eCLAT_Pre, "nodevmode"))
|
|
{
|
|
devModeEnable = false;
|
|
}
|
|
|
|
SetDevMode(devModeEnable);
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CREATE CONSOLE
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (!startupParams.bSkipConsole)
|
|
{
|
|
m_env.pConsole = new CXConsole;
|
|
|
|
if (startupParams.pPrintSync)
|
|
{
|
|
m_env.pConsole->AddOutputPrintSink(startupParams.pPrintSync);
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
if (m_pUserCallback)
|
|
{
|
|
m_pUserCallback->OnInit(this);
|
|
}
|
|
|
|
m_env.pLog->RegisterConsoleVariables();
|
|
|
|
GetIRemoteConsole()->RegisterConsoleVariables();
|
|
|
|
if (!startupParams.bSkipConsole)
|
|
{
|
|
// Register system console variables.
|
|
CreateSystemVars();
|
|
|
|
// Register Audio-related system CVars
|
|
CreateAudioVars();
|
|
|
|
// Register any AZ CVar commands created above with the AZ Console system.
|
|
AZ::ConsoleFunctorBase*& deferredHead = AZ::ConsoleFunctorBase::GetDeferredHead();
|
|
AZ::Interface<AZ::IConsole>::Get()->LinkDeferredFunctors(deferredHead);
|
|
|
|
// Callback
|
|
if (m_pUserCallback && m_env.pConsole)
|
|
{
|
|
m_pUserCallback->OnConsoleCreated(m_env.pConsole);
|
|
}
|
|
|
|
// Let listeners know its safe to register cvars
|
|
EBUS_EVENT(CrySystemEventBus, OnCrySystemCVarRegistry);
|
|
}
|
|
|
|
|
|
// Set this as soon as the system cvars got initialized.
|
|
static_cast<AZ::IO::Archive* const>(m_env.pCryPak)->SetLocalizationFolder(g_cvars.sys_localization_folder->GetString());
|
|
|
|
InlineInitializationProcessing("CSystem::Init Create console");
|
|
|
|
InitFileSystem_LoadEngineFolders(startupParams);
|
|
|
|
#if !defined(RELEASE) || defined(RELEASE_LOGGING)
|
|
// now that the system cfgs have been loaded, we can start the remote console
|
|
GetIRemoteConsole()->Update();
|
|
#endif
|
|
|
|
InlineInitializationProcessing("CSystem::Init Load Engine Folders");
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//Load config files
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
// tools may not interact with @user@
|
|
if (!gEnv->IsInToolMode())
|
|
{
|
|
if (m_pCmdLine->FindArg(eCLAT_Pre, "ResetProfile") == 0)
|
|
{
|
|
LoadConfiguration("@user@/game.cfg", 0, false);
|
|
}
|
|
}
|
|
|
|
{
|
|
// We have to load this file again since first time we did it without devmode
|
|
LoadConfiguration(m_systemConfigName.c_str());
|
|
// Optional user defined overrides
|
|
LoadConfiguration("user.cfg");
|
|
|
|
#if defined(ENABLE_STATS_AGENT)
|
|
if (m_pCmdLine->FindArg(eCLAT_Pre, "useamblecfg"))
|
|
{
|
|
LoadConfiguration("amble.cfg");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (g_cvars.sys_asserts == 0)
|
|
{
|
|
gEnv->bIgnoreAllAsserts = true;
|
|
}
|
|
if (g_cvars.sys_asserts == 2)
|
|
{
|
|
gEnv->bNoAssertDialog = true;
|
|
}
|
|
|
|
LogBuildInfo();
|
|
|
|
InlineInitializationProcessing("CSystem::Init LoadConfigurations");
|
|
|
|
#ifdef WIN32
|
|
if (g_cvars.sys_WER)
|
|
{
|
|
SetUnhandledExceptionFilter(CryEngineExceptionFilterWER);
|
|
}
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Localization
|
|
//////////////////////////////////////////////////////////////////////////
|
|
{
|
|
InitLocalization();
|
|
}
|
|
InlineInitializationProcessing("CSystem::Init InitLocalizations");
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Open basic pak files after intro movie playback started
|
|
//////////////////////////////////////////////////////////////////////////
|
|
OpenPlatformPaks();
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// AUDIO
|
|
//////////////////////////////////////////////////////////////////////////
|
|
{
|
|
if (InitAudioSystem(startupParams))
|
|
{
|
|
// Pump the Log - Audio initialization happened on a non-main thread, there may be log messages queued up.
|
|
gEnv->pLog->Update();
|
|
}
|
|
else
|
|
{
|
|
// Failure to initialize audio system is no longer a fatal or an error. A warning is sufficient.
|
|
AZ_Warning(AZ_TRACE_SYSTEM_WINDOW, false, "<Audio>: Running without any AudioSystem!");
|
|
}
|
|
}
|
|
|
|
|
|
// Compiling the default system textures can be the lengthiest portion of
|
|
// editor initialization, so it is useful to inform users that they are waiting on
|
|
// the necessary default textures to compile.
|
|
if (m_pUserCallback)
|
|
{
|
|
m_pUserCallback->OnInitProgress("First time asset processing - may take a minute...");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// System cursor
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// - Dedicated server is in console mode by default (system cursor is always shown when console is)
|
|
// - System cursor is always visible by default in Editor (we never start directly in Game Mode)
|
|
// - System cursor has to be enabled manually by the Game if needed; the custom UiCursor will typically be used instead
|
|
|
|
if (!gEnv->IsDedicated() &&
|
|
!gEnv->IsEditor())
|
|
{
|
|
AzFramework::InputSystemCursorRequestBus::Event(AzFramework::InputDeviceMouse::Id,
|
|
&AzFramework::InputSystemCursorRequests::SetSystemCursorState,
|
|
AzFramework::SystemCursorState::ConstrainedAndHidden);
|
|
}
|
|
|
|
// CONSOLE
|
|
//////////////////////////////////////////////////////////////////////////
|
|
if (!InitConsole())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (m_pUserCallback)
|
|
{
|
|
m_pUserCallback->OnInitProgress("Initializing additional systems...");
|
|
}
|
|
AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "Initializing additional systems");
|
|
|
|
|
|
InlineInitializationProcessing("CSystem::Init AIInit");
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// LEVEL SYSTEM
|
|
bool usePrefabSystemForLevels = false;
|
|
AzFramework::ApplicationRequests::Bus::BroadcastResult(
|
|
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
|
|
|
|
if (usePrefabSystemForLevels)
|
|
{
|
|
m_pLevelSystem = new LegacyLevelSystem::SpawnableLevelSystem(this);
|
|
}
|
|
else
|
|
{
|
|
// [LYN-2376] Remove once legacy slice support is removed
|
|
m_pLevelSystem = new LegacyLevelSystem::CLevelSystem(this, ILevelSystem::GetLevelsDirectoryName());
|
|
}
|
|
|
|
InlineInitializationProcessing("CSystem::Init Level System");
|
|
|
|
if (m_env.pLyShine)
|
|
{
|
|
m_env.pLyShine->PostInit();
|
|
}
|
|
|
|
InlineInitializationProcessing("CSystem::Init InitLmbrAWS");
|
|
|
|
// Az to Cry console binding
|
|
AZ::Interface<AZ::IConsole>::Get()->VisitRegisteredFunctors([](AZ::ConsoleFunctorBase* functor) { AzConsoleToCryConsoleBinder::Visit(functor); });
|
|
AzConsoleToCryConsoleBinder::s_commandRegisteredHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetConsoleCommandRegisteredEvent());
|
|
|
|
if (g_cvars.sys_float_exceptions > 0)
|
|
{
|
|
if (g_cvars.sys_float_exceptions == 3 && gEnv->IsEditor()) // Turn off float exceptions in editor if sys_float_exceptions = 3
|
|
{
|
|
g_cvars.sys_float_exceptions = 0;
|
|
}
|
|
if (g_cvars.sys_float_exceptions > 0)
|
|
{
|
|
AZ_TracePrintf(AZ_TRACE_SYSTEM_WINDOW, "Enabled float exceptions(sys_float_exceptions %d). This makes the performance slower.", g_cvars.sys_float_exceptions);
|
|
}
|
|
}
|
|
EnableFloatExceptions(g_cvars.sys_float_exceptions);
|
|
}
|
|
|
|
InlineInitializationProcessing("CSystem::Init End");
|
|
|
|
#if defined(IS_PROSDK)
|
|
SDKEvaluation::InitSDKEvaluation(gEnv, &m_pUserCallback);
|
|
#endif
|
|
|
|
InlineInitializationProcessing("CSystem::Init End");
|
|
|
|
// Send out EBus event
|
|
EBUS_EVENT(CrySystemEventBus, OnCrySystemInitialized, *this, startupParams);
|
|
|
|
// Execute any deferred commands that uses the CVar commands that were just registered
|
|
AZ::Interface<AZ::IConsole>::Get()->ExecuteDeferredConsoleCommands();
|
|
|
|
// Verify that the Maestro Gem initialized the movie system correctly. This can be removed if and when Maestro is not a required Gem
|
|
if (gEnv->IsEditor() && !gEnv->pMovieSystem)
|
|
{
|
|
AZ_Assert(false, "Error initializing the Cinematic System. Please check that the Maestro Gem is enabled for this project.");
|
|
return false;
|
|
}
|
|
|
|
if (ISystemEventDispatcher* systemEventDispatcher = GetISystemEventDispatcher())
|
|
{
|
|
systemEventDispatcher->OnSystemEvent(ESYSTEM_EVENT_GAME_POST_INIT, 0, 0);
|
|
systemEventDispatcher->OnSystemEvent(ESYSTEM_EVENT_GAME_POST_INIT_DONE, 0, 0);
|
|
}
|
|
|
|
m_bInitializedSuccessfully = true;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
static void LoadConfigurationCmd(IConsoleCmdArgs* pParams)
|
|
{
|
|
assert(pParams);
|
|
|
|
if (pParams->GetArgCount() != 2)
|
|
{
|
|
gEnv->pLog->LogError("LoadConfiguration failed, one parameter needed");
|
|
return;
|
|
}
|
|
|
|
GetISystem()->LoadConfiguration((AZStd::string("Config/") + pParams->GetArg(1)).c_str());
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------------------------------------------------------
|
|
|
|
static AZStd::string ConcatPath(const char* szPart1, const char* szPart2)
|
|
{
|
|
if (szPart1[0] == 0)
|
|
{
|
|
return szPart2;
|
|
}
|
|
|
|
AZStd::string ret;
|
|
|
|
ret.reserve(strlen(szPart1) + 1 + strlen(szPart2));
|
|
|
|
ret = szPart1;
|
|
ret += "/";
|
|
ret += szPart2;
|
|
|
|
return ret;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::CreateSystemVars()
|
|
{
|
|
assert(gEnv);
|
|
assert(gEnv->pConsole);
|
|
|
|
#if AZ_LOADSCREENCOMPONENT_ENABLED
|
|
m_game_load_screen_uicanvas_path = REGISTER_STRING("game_load_screen_uicanvas_path", "", 0, "Game load screen UiCanvas path.");
|
|
m_level_load_screen_uicanvas_path = REGISTER_STRING("level_load_screen_uicanvas_path", "", 0, "Level load screen UiCanvas path.");
|
|
m_game_load_screen_sequence_to_auto_play = REGISTER_STRING("game_load_screen_sequence_to_auto_play", "", 0, "Game load screen UiCanvas animation sequence to play on load.");
|
|
m_level_load_screen_sequence_to_auto_play = REGISTER_STRING("level_load_screen_sequence_to_auto_play", "", 0, "Level load screen UiCanvas animation sequence to play on load.");
|
|
m_game_load_screen_sequence_fixed_fps = REGISTER_FLOAT("game_load_screen_sequence_fixed_fps", 60.0f, 0, "Fixed frame rate fed to updates of the game load screen sequence.");
|
|
m_level_load_screen_sequence_fixed_fps = REGISTER_FLOAT("level_load_screen_sequence_fixed_fps", 60.0f, 0, "Fixed frame rate fed to updates of the level load screen sequence.");
|
|
m_game_load_screen_max_fps = REGISTER_FLOAT("game_load_screen_max_fps", 30.0f, 0, "Max frame rate to update the game load screen sequence.");
|
|
m_level_load_screen_max_fps = REGISTER_FLOAT("level_load_screen_max_fps", 30.0f, 0, "Max frame rate to update the level load screen sequence.");
|
|
m_game_load_screen_minimum_time = REGISTER_FLOAT("game_load_screen_minimum_time", 0.0f, 0, "Minimum amount of time to show the game load screen. Important to prevent short loads from flashing the load screen. 0 means there is no limit.");
|
|
m_level_load_screen_minimum_time = REGISTER_FLOAT("level_load_screen_minimum_time", 0.0f, 0, "Minimum amount of time to show the level load screen. Important to prevent short loads from flashing the load screen. 0 means there is no limit.");
|
|
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
|
|
|
|
REGISTER_INT("cvDoVerboseWindowTitle", 0, VF_NULL, "");
|
|
|
|
// Register an AZ Console command to quit the engine.
|
|
// The command is available even in Release builds.
|
|
static AZ::ConsoleFunctor<void, false> s_functorQuit
|
|
(
|
|
"quit",
|
|
"Quit/Shutdown the engine",
|
|
AZ::ConsoleFunctorFlags::AllowClientSet | AZ::ConsoleFunctorFlags::DontReplicate,
|
|
AZ::TypeId::CreateNull(),
|
|
[]([[maybe_unused]] const AZ::ConsoleCommandContainer& params) { GetISystem()->Quit(); }
|
|
);
|
|
|
|
m_sys_load_files_to_memory = REGISTER_STRING("sys_load_files_to_memory", "shadercache.pak", 0,
|
|
"Specify comma separated list of filenames that need to be loaded to memory.\n"
|
|
"Partial names also work. Eg. \"shader\" will load:\n"
|
|
"shaders.pak, shadercache.pak, and shadercachestartup.pak");
|
|
|
|
#ifndef _RELEASE
|
|
REGISTER_STRING_CB("sys_version", "", VF_CHEAT, "Override system file/product version", SystemVersionChanged);
|
|
#endif // #ifndef _RELEASE
|
|
|
|
attachVariable("sys_PakSaveLevelResourceList", &g_cvars.archiveVars.nSaveLevelResourceList, "Save resource list when loading level");
|
|
attachVariable("sys_PakLogInvalidFileAccess", &g_cvars.archiveVars.nLogInvalidFileAccess, "Log synchronous file access when in game");
|
|
|
|
m_sysNoUpdate = REGISTER_INT("sys_noupdate", 0, VF_CHEAT,
|
|
"Toggles updating of system with sys_script_debugger.\n"
|
|
"Usage: sys_noupdate [0/1]\n"
|
|
"Default is 0 (system updates during debug).");
|
|
|
|
#if defined(_RELEASE) && defined(CONSOLE) && !defined(ENABLE_LW_PROFILERS)
|
|
enum
|
|
{
|
|
e_sysKeyboardDefault = 0
|
|
};
|
|
#else
|
|
enum
|
|
{
|
|
e_sysKeyboardDefault = 1
|
|
};
|
|
#endif
|
|
|
|
m_svDedicatedMaxRate = REGISTER_FLOAT("sv_DedicatedMaxRate", 30.0f, 0,
|
|
"Sets the maximum update rate when running as a dedicated server.\n"
|
|
"Usage: sv_DedicatedMaxRate [5..500]\n"
|
|
"Default is 30.");
|
|
|
|
REGISTER_FLOAT("sv_DedicatedCPUPercent", 0.0f, 0,
|
|
"Sets the target CPU usage when running as a dedicated server, or disable this feature if it's zero.\n"
|
|
"Usage: sv_DedicatedCPUPercent [0..100]\n"
|
|
"Default is 0 (disabled).");
|
|
REGISTER_FLOAT("sv_DedicatedCPUVariance", 10.0f, 0,
|
|
"Sets how much the CPU can vary from sv_DedicateCPU (up or down) without adjusting the framerate.\n"
|
|
"Usage: sv_DedicatedCPUVariance [5..50]\n"
|
|
"Default is 10.");
|
|
|
|
m_sys_firstlaunch = REGISTER_INT("sys_firstlaunch", 0, 0,
|
|
"Indicates that the game was run for the first time.");
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_12
|
|
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
|
#endif
|
|
|
|
#if defined(AZ_RESTRICTED_PLATFORM)
|
|
#define AZ_RESTRICTED_SECTION SYSTEMINIT_CPP_SECTION_17
|
|
#include AZ_RESTRICTED_FILE(SystemInit_cpp)
|
|
#endif
|
|
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
|
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
|
#else
|
|
# define SYS_STREAMING_CPU_DEFAULT_VALUE 1
|
|
# define SYS_STREAMING_CPU_WORKER_DEFAULT_VALUE 5
|
|
#endif
|
|
#define DEFAULT_USE_OPTICAL_DRIVE_THREAD (gEnv->IsDedicated() ? 0 : 1)
|
|
|
|
const char* localizeFolder = "Localization";
|
|
g_cvars.sys_localization_folder = REGISTER_STRING_CB("sys_localization_folder", localizeFolder, VF_NULL,
|
|
"Sets the folder where to look for localized data.\n"
|
|
"This cvar allows for backwards compatibility so localized data under the game folder can still be found.\n"
|
|
"Usage: sys_localization_folder <folder name>\n"
|
|
"Default: Localization\n",
|
|
CSystem::OnLocalizationFolderCVarChanged);
|
|
|
|
#if (defined(WIN32) || defined(WIN64)) && defined(_DEBUG)
|
|
REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 2, 0, "Use or not use floating point exceptions.");
|
|
#else // Float exceptions by default disabled for console builds.
|
|
REGISTER_CVAR2("sys_float_exceptions", &g_cvars.sys_float_exceptions, 0, 0, "Use or not use floating point exceptions.");
|
|
#endif
|
|
|
|
REGISTER_CVAR2("sys_update_profile_time", &g_cvars.sys_update_profile_time, 1.0f, 0, "Time to keep updates timings history for.");
|
|
REGISTER_CVAR2("sys_no_crash_dialog", &g_cvars.sys_no_crash_dialog, m_bNoCrashDialog, VF_NULL, "Whether to disable the crash dialog window");
|
|
REGISTER_CVAR2("sys_no_error_report_window", &g_cvars.sys_no_error_report_window, m_bNoErrorReportWindow, VF_NULL, "Whether to disable the error report list");
|
|
#if defined(_RELEASE)
|
|
if (!gEnv->IsDedicated())
|
|
{
|
|
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 1, 0, "Enables Windows Error Reporting");
|
|
}
|
|
#else
|
|
REGISTER_CVAR2("sys_WER", &g_cvars.sys_WER, 0, 0, "Enables Windows Error Reporting");
|
|
#endif
|
|
|
|
const int DEFAULT_DUMP_TYPE = 2;
|
|
|
|
REGISTER_CVAR2("sys_dump_type", &g_cvars.sys_dump_type, DEFAULT_DUMP_TYPE, VF_NULL,
|
|
"Specifies type of crash dump to create - see MINIDUMP_TYPE in dbghelp.h for full list of values\n"
|
|
"0: Do not create a minidump\n"
|
|
"1: Create a small minidump (stacktrace)\n"
|
|
"2: Create a medium minidump (+ some variables)\n"
|
|
"3: Create a full minidump (+ all memory)\n"
|
|
);
|
|
REGISTER_CVAR2("sys_dump_aux_threads", &g_cvars.sys_dump_aux_threads, 1, VF_NULL, "Dumps callstacks of other threads in case of a crash");
|
|
|
|
#if (defined(WIN32) || defined(WIN64)) && defined(_RELEASE)
|
|
const int DEFAULT_SYS_MAX_FPS = 0;
|
|
#else
|
|
const int DEFAULT_SYS_MAX_FPS = -1;
|
|
#endif
|
|
REGISTER_CVAR2("sys_MaxFPS", &g_cvars.sys_MaxFPS, DEFAULT_SYS_MAX_FPS, VF_NULL, "Limits the frame rate to specified number n (if n>0 and if vsync is disabled).\n"
|
|
" 0 = on PC if vsync is off auto throttles fps while in menu or game is paused (default)\n"
|
|
"-1 = off");
|
|
|
|
REGISTER_CVAR2("sys_maxTimeStepForMovieSystem", &g_cvars.sys_maxTimeStepForMovieSystem, 0.1f, VF_NULL, "Caps the time step for the movie system so that a cut-scene won't be jumped in the case of an extreme stall.");
|
|
|
|
REGISTER_CVAR2("sys_report_files_not_found_in_paks", &g_cvars.sys_report_files_not_found_in_paks, 0, VF_NULL, "Reports when files are searched for in paks and not found. 1 = log, 2 = warning, 3 = error");
|
|
|
|
REGISTER_COMMAND("sys_crashtest", CmdCrashTest, VF_CHEAT, "Make the game crash\n"
|
|
"0=off\n"
|
|
"1=null pointer exception\n"
|
|
"2=floating point exception\n"
|
|
"3=memory allocation exception\n"
|
|
"4=cry fatal error is called\n"
|
|
"5=memory allocation for small blocks\n"
|
|
"6=assert\n"
|
|
"7=debugbreak\n"
|
|
"8=10min sleep"
|
|
);
|
|
|
|
REGISTER_FLOAT("sys_scale3DMouseTranslation", 0.2f, 0, "Scales translation speed of supported 3DMouse devices.");
|
|
REGISTER_FLOAT("sys_Scale3DMouseYPR", 0.05f, 0, "Scales rotation speed of supported 3DMouse devices.");
|
|
|
|
REGISTER_INT("capture_frames", 0, 0, "Enables capturing of frames. 0=off, 1=on");
|
|
REGISTER_STRING("capture_folder", "CaptureOutput", 0, "Specifies sub folder to write captured frames.");
|
|
REGISTER_INT("capture_frame_once", 0, 0, "Makes capture single frame only");
|
|
REGISTER_STRING("capture_file_name", "", 0, "If set, specifies the path and name to use for the captured frame");
|
|
REGISTER_STRING("capture_file_prefix", "", 0, "If set, specifies the prefix to use for the captured frame instead of the default 'Frame'.");
|
|
|
|
m_gpu_particle_physics = REGISTER_INT("gpu_particle_physics", 0, VF_REQUIRE_APP_RESTART, "Enable GPU physics if available (0=off / 1=enabled).");
|
|
assert(m_gpu_particle_physics);
|
|
|
|
REGISTER_COMMAND("LoadConfig", &LoadConfigurationCmd, 0,
|
|
"Load .cfg file from disk (from the {Game}/Config directory)\n"
|
|
"e.g. LoadConfig lowspec.cfg\n"
|
|
"Usage: LoadConfig <filename>");
|
|
assert(m_env.pConsole);
|
|
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F12", "Screenshot");
|
|
m_env.pConsole->CreateKeyBind("alt_keyboard_key_function_F11", "RecordClip");
|
|
|
|
/*
|
|
// experimental feature? - needs to be created very early
|
|
m_sys_filecache = REGISTER_INT("sys_FileCache",0,0,
|
|
"To speed up loading from non HD media\n"
|
|
"0=off / 1=enabled");
|
|
*/
|
|
REGISTER_CVAR2("sys_trackview", &g_cvars.sys_trackview, 1, 0, "Enables TrackView Update");
|
|
|
|
//Defines selected language.
|
|
REGISTER_STRING_CB("g_language", "", VF_NULL, "Defines which language pak is loaded", CSystem::OnLanguageCVarChanged);
|
|
|
|
// adding CVAR to toggle assert verbosity level
|
|
const int defaultAssertValue = 1;
|
|
REGISTER_CVAR2_CB("sys_asserts", &g_cvars.sys_asserts, defaultAssertValue, VF_CHEAT,
|
|
"0 = Suppress Asserts\n"
|
|
"1 = Log Asserts\n"
|
|
"2 = Show Assert Dialog\n"
|
|
"3 = Crashes the Application on Assert\n"
|
|
"Note: when set to '0 = Suppress Asserts', assert expressions are still evaluated. To turn asserts into a no-op, undefine AZ_ENABLE_TRACING and recompile.",
|
|
OnAssertLevelCvarChanged);
|
|
CSystem::SetAssertLevel(defaultAssertValue);
|
|
|
|
REGISTER_CVAR2("sys_error_debugbreak", &g_cvars.sys_error_debugbreak, 0, VF_CHEAT, "__debugbreak() if a VALIDATOR_ERROR_DBGBREAK message is hit");
|
|
|
|
REGISTER_STRING("dlc_directory", "", 0, "Holds the path to the directory where DLC should be installed to and read from");
|
|
|
|
#if defined(WIN32) || defined(WIN64)
|
|
REGISTER_INT("sys_screensaver_allowed", 0, VF_NULL, "Specifies if screen saver is allowed to start up while the game is running.");
|
|
#endif
|
|
|
|
// Since the UI Canvas Editor is incomplete, we have a variable to enable it.
|
|
// By default it is now enabled. Modify system.cfg or game.cfg to disable it
|
|
REGISTER_INT("sys_enableCanvasEditor", 1, VF_NULL, "Enables the UI Canvas Editor");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
void CSystem::CreateAudioVars()
|
|
{
|
|
assert(gEnv);
|
|
assert(gEnv->pConsole);
|
|
|
|
m_sys_audio_disable = REGISTER_INT("sys_audio_disable", 0, VF_REQUIRE_APP_RESTART,
|
|
"Specifies whether to use the NULLAudioSystem in place of the regular AudioSystem\n"
|
|
"Usage: sys_audio_disable [0/1]\n"
|
|
"0: use regular AudioSystem.\n"
|
|
"1: use NullAudioSystem (disable all audio functionality).\n"
|
|
"Default: 0 (enable audio functionality)");
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
void CSystem::AddCVarGroupDirectory(const AZStd::string& sPath)
|
|
{
|
|
CryLog("creating CVarGroups from directory '%s' ...", sPath.c_str());
|
|
INDENT_LOG_DURING_SCOPE();
|
|
|
|
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(ConcatPath(sPath.c_str(), "*.cfg").c_str());
|
|
|
|
if (!handle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
do
|
|
{
|
|
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
|
|
{
|
|
if (handle.m_filename != "." && handle.m_filename != "..")
|
|
{
|
|
AddCVarGroupDirectory(ConcatPath(sPath.c_str(), handle.m_filename.data()));
|
|
}
|
|
}
|
|
} while (handle = gEnv->pCryPak->FindNext(handle));
|
|
|
|
gEnv->pCryPak->FindClose(handle);
|
|
}
|
|
|
|
bool CSystem::RegisterErrorObserver(IErrorObserver* errorObserver)
|
|
{
|
|
return stl::push_back_unique(m_errorObservers, errorObserver);
|
|
}
|
|
|
|
bool CSystem::UnregisterErrorObserver(IErrorObserver* errorObserver)
|
|
{
|
|
return stl::find_and_erase(m_errorObservers, errorObserver);
|
|
}
|
|
|
|
void CSystem::OnAssert(const char* condition, const char* message, const char* fileName, unsigned int fileLineNumber)
|
|
{
|
|
if (g_cvars.sys_asserts == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
std::vector<IErrorObserver*>::const_iterator end = m_errorObservers.end();
|
|
for (std::vector<IErrorObserver*>::const_iterator it = m_errorObservers.begin(); it != end; ++it)
|
|
{
|
|
(*it)->OnAssert(condition, message, fileName, fileLineNumber);
|
|
}
|
|
if (g_cvars.sys_asserts > 1)
|
|
{
|
|
CryFatalError("<assert> %s\r\n%s\r\n%s (%d)\r\n", condition, message, fileName, fileLineNumber);
|
|
}
|
|
}
|
|
|
|
void CSystem::OnFatalError(const char* message)
|
|
{
|
|
std::vector<IErrorObserver*>::const_iterator end = m_errorObservers.end();
|
|
for (std::vector<IErrorObserver*>::const_iterator it = m_errorObservers.begin(); it != end; ++it)
|
|
{
|
|
(*it)->OnFatalError(message);
|
|
}
|
|
}
|
|
|
|
bool CSystem::IsAssertDialogVisible() const
|
|
{
|
|
return m_bIsAsserting;
|
|
}
|
|
|
|
void CSystem::SetAssertVisible(bool bAssertVisble)
|
|
{
|
|
m_bIsAsserting = bAssertVisble;
|
|
}
|