Integrating up through commit 90f050496

This commit is contained in:
alexpete
2021-04-07 14:03:29 -07:00
parent 8f2ed080a9
commit c2cbd430fe
2694 changed files with 285622 additions and 176874 deletions
+28 -10
View File
@@ -19,6 +19,7 @@
#include "System.h"
#include "IStreamEngine.h"
#include <AzFramework/Archive/Archive.h>
#include <AzFramework/API/ApplicationAPI.h>
#include "ResourceManager.h"
#define MEGA_BYTE 1024* 1024
@@ -360,20 +361,37 @@ void CAsyncPakManager::StreamAsyncOnComplete(
}
else
{
//
// ugly hack - depending on the pak file pak may need special root info / open flags
//
if (pLayerPak->layername.find("level.pak") != string::npos)
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels,
&AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (usePrefabSystemForLevels)
{
gEnv->pCryPak->OpenPack({ pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos)
{
gEnv->pCryPak->OpenPack("@assets@", { pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL);
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else
{
gEnv->pCryPak->OpenPack("@assets@", { pLayerPak->filename.c_str(), pLayerPak->filename.size() }, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
//
// ugly hack - depending on the pak file pak may need special root info / open flags
//
if (pLayerPak->layername.find("level.pak") != string::npos)
{
gEnv->pCryPak->OpenPack(
{pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32, NULL);
}
else if (pLayerPak->layername.find("levelshadercache.pak") != string::npos)
{
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_PATH_REAL, NULL);
}
else
{
gEnv->pCryPak->OpenPack(
"@assets@", {pLayerPak->filename.c_str(), pLayerPak->filename.size()}, AZ::IO::IArchive::FLAGS_FILENAMES_AS_CRC32,
NULL);
}
}
gEnv->pCryPak->LoadPakToMemory(pLayerPak->filename.c_str(), AZ::IO::IArchive::eInMemoryPakLocale_GPU, pLayerPak->pData);
}
File diff suppressed because it is too large Load Diff
@@ -16,6 +16,8 @@
#include "ILevelSystem.h"
#include <AzFramework/Archive/IArchive.h>
// [LYN-2376] Remove the entire file once legacy slice support is removed
namespace LegacyLevelSystem
{
@@ -24,75 +26,38 @@ class CLevelInfo
{
friend class CLevelSystem;
public:
CLevelInfo()
: m_heightmapSize(0)
, m_bMetaDataRead(false)
, m_isModLevel(false)
, m_scanTag(ILevelSystem::TAG_UNKNOWN)
, m_levelTag(ILevelSystem::TAG_UNKNOWN)
{
SwapEndian(m_scanTag, eBigEndian);
SwapEndian(m_levelTag, eBigEndian);
};
CLevelInfo() = default;
// ILevelInfo
virtual const char* GetName() const { return m_levelName.c_str(); };
virtual const bool IsOfType(const char* sType) const;
virtual const char* GetPath() const { return m_levelPath.c_str(); };
virtual const char* GetPaks() const { return m_levelPaks.c_str(); };
virtual bool GetIsModLevel() const { return m_isModLevel; }
virtual const uint32 GetScanTag() const { return m_scanTag; }
virtual const uint32 GetLevelTag() const { return m_levelTag; }
virtual const char* GetDisplayName() const;
virtual const char* GetPreviewImagePath() const { return m_previewImagePath.c_str(); }
virtual const char* GetBackgroundImagePath() const { return m_backgroundImagePath.c_str(); }
virtual const char* GetMinimapImagePath() const {return m_minimapImagePath.c_str(); }
//virtual const ILevelInfo::TStringVec& GetMusicLibs() const { return m_musicLibs; }; // Gets reintroduced when level specific music data loading is implemented.
virtual const bool MetadataLoaded() const { return m_bMetaDataRead; }
virtual int GetGameTypeCount() const { return m_gameTypes.size(); };
virtual const ILevelInfo::TGameTypeInfo* GetGameType(int gameType) const { return &m_gameTypes[gameType]; };
virtual bool SupportsGameType(const char* gameTypeName) const;
virtual const ILevelInfo::TGameTypeInfo* GetDefaultGameType() const;
virtual bool HasGameRules() const{ return !m_gamerules.empty(); }
virtual const ILevelInfo::SMinimapInfo& GetMinimapInfo() const { return m_minimapInfo; }
virtual const char* GetDefaultGameRules() const{ return m_gamerules.empty() ? NULL : m_gamerules[0].c_str(); }
virtual ILevelInfo::TStringVec GetGameRules() const{ return m_gamerules; }
virtual const char* GetName() const { return m_levelName.c_str(); }
virtual const char* GetPath() const { return m_levelPath.c_str(); }
virtual const char* GetAssetName() const { return m_levelAssetName.c_str(); }
// ~ILevelInfo
void GetMemoryUsage(ICrySizer*) const;
private:
void ReadMetaData();
bool ReadInfo();
bool OpenLevelPak();
void CloseLevelPak();
string m_levelName;
string m_levelPath;
string m_levelPaks;
string m_levelDisplayName;
string m_previewImagePath;
string m_backgroundImagePath;
string m_minimapImagePath;
AZStd::string m_defaultGameTypeName;
AZStd::string m_levelName;
AZStd::string m_levelPath;
AZStd::string m_levelAssetName;
string m_levelPakFullPath;
AZStd::string m_levelPakFullPath;
TStringVec m_gamerules;
int m_heightmapSize;
uint32 m_scanTag;
uint32 m_levelTag;
bool m_bMetaDataRead;
std::vector<ILevelInfo::TGameTypeInfo> m_gameTypes;
bool m_isModLevel;
SMinimapInfo m_minimapInfo;
bool m_isPak = false;
};
DynArray<string> m_levelTypeList;
bool m_isPak = false;
struct ILevel
{
virtual ~ILevel() = default;
virtual void Release() = 0;
virtual ILevelInfo* GetLevelInfo() = 0;
};
class CLevel
@@ -121,10 +86,7 @@ public:
void Release() { delete this; };
// ILevelSystem
virtual DynArray<string>* GetLevelTypeList();
virtual void Rescan(const char* levelsFolder, const uint32 tag);
void ScanFolder(const char* subfolder, bool modFolder, const uint32 tag) override;
void PopulateLevels(string searchPattern, string& folder, AZ::IO::IArchive* pPak, bool& modFolder, const uint32& tag, bool fromFileSystemOnly) override;
virtual void Rescan(const char* levelsFolder);
virtual int GetLevelCount();
virtual ILevelInfo* GetLevelInfo(int level);
virtual ILevelInfo* GetLevelInfo(const char* levelName);
@@ -132,74 +94,81 @@ public:
virtual void AddListener(ILevelSystemListener* pListener);
virtual void RemoveListener(ILevelSystemListener* pListener);
virtual ILevel* GetCurrentLevel() const { return m_pCurrentLevel; }
virtual ILevel* LoadLevel(const char* levelName);
virtual void UnLoadLevel();
virtual ILevel* SetEditorLoadedLevel(const char* levelName, bool bReadLevelInfoMetaData = false);
virtual void PrepareNextLevel(const char* levelName);
virtual float GetLastLevelLoadTime() { return m_fLastLevelLoadTime; };
virtual bool LoadLevel(const char* levelName);
virtual void UnloadLevel();
virtual bool IsLevelLoaded() { return m_bLevelLoaded; }
const char* GetCurrentLevelName() const override
{
if (m_pCurrentLevel && m_pCurrentLevel->GetLevelInfo())
{
return m_pCurrentLevel->GetLevelInfo()->GetName();
}
else
{
return "";
}
}
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
virtual void SetLevelLoadFailed(bool loadFailed) { m_levelLoadFailed = loadFailed; }
virtual bool GetLevelLoadFailed() { return m_levelLoadFailed; }
// Unsupported by legacy level system.
virtual AZ::Data::AssetType GetLevelAssetType() const { return {}; }
// ~ILevelSystem
void GetMemoryUsage(ICrySizer* s) const;
void SaveOpenedFilesList();
private:
float GetLastLevelLoadTime() { return m_fLastLevelLoadTime; }
void ScanFolder(const char* subfolder, bool modFolder);
void PopulateLevels(
AZStd::string searchPattern, AZStd::string& folder, AZ::IO::IArchive* pPak, bool& modFolder, bool fromFileSystemOnly);
void PrepareNextLevel(const char* levelName);
ILevel* LoadLevelInternal(const char* _levelName);
// ILevelSystemListener events notification
// Methods to notify ILevelSystemListener
void OnLevelNotFound(const char* levelName);
void OnLoadingStart(ILevelInfo* pLevel);
void OnLoadingComplete(ILevel* pLevel);
void OnLoadingError(ILevelInfo* pLevel, const char* error);
void OnLoadingProgress(ILevelInfo* pLevel, int progressAmount);
void OnUnloadComplete(ILevel* pLevel);
void OnLoadingStart(const char* levelName);
void OnLoadingComplete(const char* levelName);
void OnLoadingError(const char* levelName, const char* error);
void OnLoadingProgress(const char* levelName, int progressAmount);
void OnUnloadComplete(const char* levelName);
// lowercase string and replace backslashes with forward slashes
// TODO: move this to a more general place in CryEngine
string& UnifyName(string& name);
void LogLoadingTime();
bool LoadLevelInfo(CLevelInfo& levelInfo);
// internal get functions for the level infos ... they preserve the type and don't
// directly cast to the interface
CLevelInfo* GetLevelInfoInternal(int level);
CLevelInfo* GetLevelInfoInternal(const char* levelName);
CLevelInfo* GetLevelInfoInternal(const AZStd::string& levelName);
ISystem* m_pSystem;
std::vector<CLevelInfo> m_levelInfos;
string m_levelsFolder;
AZStd::vector<CLevelInfo> m_levelInfos;
AZStd::string m_levelsFolder;
ILevel* m_pCurrentLevel;
ILevelInfo* m_pLoadingLevelInfo;
string m_lastLevelName;
AZStd::string m_lastLevelName;
float m_fLastLevelLoadTime;
float m_fFilteredProgress;
float m_fLastTime;
bool m_bLevelLoaded;
bool m_bRecordingFileOpens;
bool m_levelLoadFailed = false;
int m_nLoadedLevelsCount;
CTimeValue m_levelLoadStartTime;
static int s_loadCount;
std::vector<ILevelSystemListener*> m_listeners;
DynArray<string> m_levelTypeList;
AZStd::vector<ILevelSystemListener*> m_listeners;
AZ::IO::IArchive::LevelPackOpenEvent::Handler m_levelPackOpenHandler;
AZ::IO::IArchive::LevelPackCloseEvent::Handler m_levelPackCloseHandler;
static constexpr const char* LevelPakName = "level.pak";
};
} // namespace LegacyLevelSystem
@@ -0,0 +1,709 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include "CrySystem_precompiled.h"
#include "SpawnableLevelSystem.h"
#include <IAudioSystem.h>
#include "IMovieSystem.h"
#include <IResourceManager.h>
#include "IDeferredCollisionEvent.h"
#include <LoadScreenBus.h>
#include <AzCore/Debug/AssetTracking.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/FileOperations.h>
#include <AzFramework/Entity/GameEntityContextBus.h>
#include <AzFramework/Input/Buses/Requests/InputChannelRequestBus.h>
#include "MainThreadRenderRequestBus.h"
#include <LyShine/ILyShine.h>
#include <AzCore/Component/TickBus.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/StringFunc/StringFunc.h>
#include <AzCore/Script/ScriptSystemBus.h>
namespace LegacyLevelSystem
{
//------------------------------------------------------------------------
static void LoadLevel(const AZ::ConsoleCommandContainer& arguments)
{
AZ_Error("SpawnableLevelSystem", arguments.empty(), "LoadLevel requires a level file name to be provided.");
AZ_Error("SpawnableLevelSystem", arguments.size() > 1, "LoadLevel requires a single level file name to be provided.");
if (!arguments.empty() && gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
{
gEnv->pSystem->GetILevelSystem()->LoadLevel(arguments[0].data());
}
}
//------------------------------------------------------------------------
static void UnloadLevel([[maybe_unused]] const AZ::ConsoleCommandContainer& arguments)
{
AZ_Warning("SpawnableLevelSystem", !arguments.empty(), "UnloadLevel doesn't use any arguments.");
if (gEnv->pSystem && gEnv->pSystem->GetILevelSystem() && !gEnv->IsEditor())
{
gEnv->pSystem->GetILevelSystem()->UnloadLevel();
if (gEnv->p3DEngine)
{
gEnv->p3DEngine->LoadEmptyLevel();
}
}
}
AZ_CONSOLEFREEFUNC(LoadLevel, AZ::ConsoleFunctorFlags::Null, "Unloads the current level and loads a new one with the given asset name");
AZ_CONSOLEFREEFUNC(UnloadLevel, AZ::ConsoleFunctorFlags::Null, "Unloads the current level");
//------------------------------------------------------------------------
SpawnableLevelSystem::SpawnableLevelSystem(ISystem* pSystem)
: m_pSystem(pSystem)
{
LOADING_TIME_PROFILE_SECTION;
CRY_ASSERT(pSystem);
m_fLastLevelLoadTime = 0;
m_fLastTime = 0;
m_bLevelLoaded = false;
m_levelLoadStartTime.SetValue(0);
m_nLoadedLevelsCount = 0;
AZ_Assert(gEnv && gEnv->pCryPak, "gEnv and CryPak must be initialized for loading levels.");
if (!gEnv || !gEnv->pCryPak)
{
return;
}
auto pPak = gEnv->pCryPak;
AzFramework::RootSpawnableNotificationBus::Handler::BusConnect();
}
//------------------------------------------------------------------------
SpawnableLevelSystem::~SpawnableLevelSystem()
{
AzFramework::RootSpawnableNotificationBus::Handler::BusDisconnect();
}
void SpawnableLevelSystem::Release()
{
delete this;
}
bool SpawnableLevelSystem::IsLevelLoaded()
{
return m_bLevelLoaded;
}
const char* SpawnableLevelSystem::GetCurrentLevelName() const
{
return m_bLevelLoaded ? m_lastLevelName.c_str() : "";
}
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
void SpawnableLevelSystem::SetLevelLoadFailed(bool loadFailed)
{
m_levelLoadFailed = loadFailed;
}
bool SpawnableLevelSystem::GetLevelLoadFailed()
{
return m_levelLoadFailed;
}
AZ::Data::AssetType SpawnableLevelSystem::GetLevelAssetType() const
{
return azrtti_typeid<AzFramework::Spawnable>();
}
// The following methods are deprecated from ILevelSystem and will be removed once slice support is removed.
// [LYN-2376] Remove once legacy slice support is removed
void SpawnableLevelSystem::Rescan([[maybe_unused]] const char* levelsFolder)
{
AZ_Assert(false, "Rescan - No longer supported.");
}
// [LYN-2376] Remove once legacy slice support is removed
int SpawnableLevelSystem::GetLevelCount()
{
AZ_Assert(false, "GetLevelCount - No longer supported.");
return 0;
}
// [LYN-2376] Remove once legacy slice support is removed
ILevelInfo* SpawnableLevelSystem::GetLevelInfo([[maybe_unused]] int level)
{
AZ_Assert(false, "GetLevelInfo - No longer supported.");
return nullptr;
}
// [LYN-2376] Remove once legacy slice support is removed
ILevelInfo* SpawnableLevelSystem::GetLevelInfo([[maybe_unused]] const char* levelName)
{
AZ_Assert(false, "GetLevelInfo - No longer supported.");
return nullptr;
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::AddListener(ILevelSystemListener* pListener)
{
AZStd::vector<ILevelSystemListener*>::iterator it = AZStd::find(m_listeners.begin(), m_listeners.end(), pListener);
if (it == m_listeners.end())
{
m_listeners.push_back(pListener);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::RemoveListener(ILevelSystemListener* pListener)
{
AZStd::vector<ILevelSystemListener*>::iterator it = AZStd::find(m_listeners.begin(), m_listeners.end(), pListener);
if (it != m_listeners.end())
{
m_listeners.erase(it);
}
}
//------------------------------------------------------------------------
bool SpawnableLevelSystem::LoadLevel(const char* levelName)
{
if (gEnv->IsEditor())
{
AZ_TracePrintf("CrySystem::CLevelSystem", "LoadLevel for %s was called in the editor - not actually loading.\n", levelName);
return false;
}
// If a level is currently loaded, unload it before loading the next one.
if (IsLevelLoaded())
{
UnloadLevel();
}
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_PREPARE, 0, 0);
PrepareNextLevel(levelName);
bool result = LoadLevelInternal(levelName);
if (result)
{
OnLoadingComplete(levelName);
}
return result;
}
//------------------------------------------------------------------------
bool SpawnableLevelSystem::LoadLevelInternal(const char* levelName)
{
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START);
AZ_ASSET_NAMED_SCOPE("Level: %s", levelName);
INDENT_LOG_DURING_SCOPE();
AZ::Data::AssetId rootSpawnableAssetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
rootSpawnableAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, levelName, nullptr, false);
if (!rootSpawnableAssetId.IsValid())
{
OnLoadingError(levelName, "AssetCatalog has no entry for the requested level.");
return false;
}
// This scope is specifically used for marking a loading time profile section
{
LOADING_TIME_PROFILE_SECTION;
m_bLevelLoaded = false;
m_lastLevelName = levelName;
gEnv->pConsole->SetScrollMax(600);
ICVar* con_showonload = gEnv->pConsole->GetCVar("con_showonload");
if (con_showonload && con_showonload->GetIVal() != 0)
{
gEnv->pConsole->ShowConsole(true);
ICVar* g_enableloadingscreen = gEnv->pConsole->GetCVar("g_enableloadingscreen");
if (g_enableloadingscreen)
{
g_enableloadingscreen->Set(0);
}
}
// Reset the camera to (1,1,1) (not (0,0,0) which is the invalid/uninitialised state,
// to avoid the hack in the renderer to not show anything if the camera is at the origin).
CCamera defaultCam;
defaultCam.SetPosition(Vec3(1.0f));
m_pSystem->SetViewCamera(defaultCam);
OnLoadingStart(levelName);
auto pPak = gEnv->pCryPak;
m_pSystem->SetThreadState(ESubsys_Physics, false);
ICVar* pSpamDelay = gEnv->pConsole->GetCVar("log_SpamDelay");
float spamDelay = 0.0f;
if (pSpamDelay)
{
spamDelay = pSpamDelay->GetFVal();
pSpamDelay->Set(0.0f);
}
if (gEnv->p3DEngine)
{
AZ::IO::PathView levelPath(levelName);
AZStd::string parentPath(levelPath.ParentPath().Native());
static constexpr const char* defaultGameTypeName = "Mission0";
bool is3DEngineLoaded = gEnv->IsEditor() ? gEnv->p3DEngine->InitLevelForEditor(parentPath.c_str(), defaultGameTypeName)
: gEnv->p3DEngine->LoadLevel(parentPath.c_str(), defaultGameTypeName);
if (!is3DEngineLoaded)
{
OnLoadingError(levelName, "3DEngine failed to handle loading the level");
return 0;
}
}
// Parse level specific config data.
AZStd::string const sLevelNameOnly(PathUtil::GetFileName(levelName));
if (!sLevelNameOnly.empty())
{
const char* controlsPath = nullptr;
Audio::AudioSystemRequestBus::BroadcastResult(controlsPath, &Audio::AudioSystemRequestBus::Events::GetControlsPath);
if (controlsPath)
{
AZStd::string sAudioLevelPath(controlsPath);
sAudioLevelPath.append("levels/");
sAudioLevelPath += sLevelNameOnly;
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_CONTROLS_DATA> oAMData(
sAudioLevelPath.c_str(), Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags =
(Audio::eARF_PRIORITY_HIGH |
Audio::eARF_EXECUTE_BLOCKING); // Needs to be blocking so data is available for next preloading request!
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_PARSE_PRELOADS_DATA> oAMData2(
sAudioLevelPath.c_str(), Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::TAudioPreloadRequestID nPreloadRequestID = INVALID_AUDIO_PRELOAD_REQUEST_ID;
Audio::AudioSystemRequestBus::BroadcastResult(
nPreloadRequestID, &Audio::AudioSystemRequestBus::Events::GetAudioPreloadRequestID, sLevelNameOnly.c_str());
if (nPreloadRequestID != INVALID_AUDIO_PRELOAD_REQUEST_ID)
{
Audio::SAudioManagerRequestData<Audio::eAMRT_PRELOAD_SINGLE_REQUEST> requestData(nPreloadRequestID, true);
oAudioRequestData.pData = &requestData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
}
}
}
AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable(
rootSpawnableAssetId, azrtti_typeid<AzFramework::Spawnable>(), levelName);
m_rootSpawnableId = rootSpawnableAssetId;
m_rootSpawnableGeneration = AzFramework::RootSpawnableInterface::Get()->AssignRootSpawnable(rootSpawnable);
//////////////////////////////////////////////////////////////////////////
// Movie system must be reset after entities.
//////////////////////////////////////////////////////////////////////////
IMovieSystem* movieSys = gEnv->pMovieSystem;
if (movieSys != NULL)
{
// bSeekAllToStart needs to be false here as it's only of interest in the editor
movieSys->Reset(true, false);
}
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PRECACHE);
//////////////////////////////////////////////////////////////////////////
// Notify 3D engine that loading finished
//////////////////////////////////////////////////////////////////////////
if (gEnv->p3DEngine)
{
gEnv->p3DEngine->PostLoadLevel();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
gEnv->pConsole->SetScrollMax(600 / 2);
pPak->GetResourceList(AZ::IO::IArchive::RFOM_NextLevel)->Clear();
if (pSpamDelay)
{
pSpamDelay->Set(spamDelay);
}
m_bLevelLoaded = true;
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_END);
}
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_END, 0, 0);
if (auto cvar = gEnv->pConsole->GetCVar("sv_map"); cvar)
{
cvar->Set(levelName);
}
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_PRECACHE_START, 0, 0);
m_pSystem->SetThreadState(ESubsys_Physics, true);
return true;
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::PrepareNextLevel(const char* levelName)
{
AZ::Data::AssetId rootSpawnableAssetId;
AZ::Data::AssetCatalogRequestBus::BroadcastResult(
rootSpawnableAssetId, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetIdByPath, levelName, nullptr, false);
if (!rootSpawnableAssetId.IsValid())
{
// alert the listener
OnLevelNotFound(levelName);
return;
}
// This work not required in-editor.
if (!gEnv || !gEnv->IsEditor())
{
m_levelLoadStartTime = gEnv->pTimer->GetAsyncTime();
// switched to level heap, so now imm start the loading screen (renderer will be reinitialized in the levelheap)
gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START_LOADINGSCREEN, 0, 0);
gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_LEVEL_LOAD_START_PREPARE);
}
OnPrepareNextLevel(levelName);
}
void SpawnableLevelSystem::OnPrepareNextLevel(const char* levelName)
{
AZ_TracePrintf("LevelSystem", "Level system is preparing to load '%s'\n", levelName);
for (auto& listener : m_listeners)
{
listener->OnPrepareNextLevel(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLevelNotFound(const char* levelName)
{
AZ_Error("LevelSystem", false, "Requested level not found: '%s'\n", levelName);
for (auto& listener : m_listeners)
{
listener->OnLevelNotFound(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingStart(const char* levelName)
{
AZ_TracePrintf("LevelSystem", "Level system is loading '%s'\n", levelName);
if (gEnv->pCryPak->GetRecordFileOpenList() == AZ::IO::IArchive::RFOM_EngineStartup)
{
gEnv->pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_Level);
}
m_fLastTime = gEnv->pTimer->GetAsyncCurTime();
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_START, 0, 0);
LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
for (auto& listener : m_listeners)
{
listener->OnLoadingStart(levelName);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingError(const char* levelName, const char* error)
{
AZ_Error("LevelSystem", false, "Error loading level '%s': %s\n", levelName, error);
if (gEnv->pRenderer)
{
gEnv->pRenderer->SetTexturePrecaching(false);
}
for (auto& listener : m_listeners)
{
listener->OnLoadingError(levelName, error);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingComplete(const char* levelName)
{
CTimeValue t = gEnv->pTimer->GetAsyncTime();
m_fLastLevelLoadTime = (t - m_levelLoadStartTime).GetSeconds();
LogLoadingTime();
m_nLoadedLevelsCount++;
// Hide console after loading.
gEnv->pConsole->ShowConsole(false);
for (auto& listener : m_listeners)
{
listener->OnLoadingComplete(levelName);
}
#if AZ_LOADSCREENCOMPONENT_ENABLED
EBUS_EVENT(LoadScreenBus, Stop);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
AZ_TracePrintf("LevelSystem", "Level load complete: '%s'\n", levelName);
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnLoadingProgress(const char* levelName, int progressAmount)
{
for (auto& listener : m_listeners)
{
listener->OnLoadingProgress(levelName, progressAmount);
}
}
//------------------------------------------------------------------------
void SpawnableLevelSystem::OnUnloadComplete(const char* levelName)
{
for (auto& listener : m_listeners)
{
listener->OnUnloadComplete(levelName);
}
AZ_TracePrintf("LevelSystem", "Level unload complete: '%s'\n", levelName);
}
//////////////////////////////////////////////////////////////////////////
void SpawnableLevelSystem::LogLoadingTime()
{
if (gEnv->IsEditor())
{
return;
}
if (!GetISystem()->IsDevMode())
{
return;
}
char vers[128];
GetISystem()->GetFileVersion().ToString(vers, sizeof(vers));
const char* sChain = "";
if (m_nLoadedLevelsCount > 0)
{
sChain = " (Chained)";
}
AZStd::string text;
text.format(
"Game Level Load Time: [%s] Level %s loaded in %.2f seconds%s", vers, m_lastLevelName.c_str(), m_fLastLevelLoadTime, sChain);
gEnv->pLog->Log(text.c_str());
}
//////////////////////////////////////////////////////////////////////////
void SpawnableLevelSystem::UnloadLevel()
{
if (gEnv->IsEditor())
{
return;
}
if (m_lastLevelName.empty())
{
return;
}
AZ_TracePrintf("LevelSystem", "UnloadLevel Start\n");
INDENT_LOG_DURING_SCOPE();
// Flush core buses. We're about to unload Cry modules and need to ensure we don't have module-owned functions left behind.
AZ::Data::AssetBus::ExecuteQueuedEvents();
AZ::TickBus::ExecuteQueuedEvents();
AZ::MainThreadRenderRequestBus::ExecuteQueuedEvents();
if (gEnv && gEnv->pSystem)
{
// clear all error messages to prevent stalling due to runtime file access check during chainloading
gEnv->pSystem->ClearErrorMessages();
}
if (gEnv && gEnv->pCryPak)
{
gEnv->pCryPak->DisableRuntimeFileAccess(false);
}
CTimeValue tBegin = gEnv->pTimer->GetAsyncTime();
I3DEngine* p3DEngine = gEnv->p3DEngine;
if (p3DEngine)
{
IDeferredPhysicsEventManager* pPhysEventManager = p3DEngine->GetDeferredPhysicsEventManager();
if (pPhysEventManager)
{
// clear deferred physics queues before renderer, since we could have jobs running
// which access a rendermesh
pPhysEventManager->ClearDeferredEvents();
}
}
// AM: Flush render thread (Flush is not exposed - using EndFrame())
// We are about to delete resources that could be in use
if (gEnv->pRenderer)
{
gEnv->pRenderer->EndFrame();
bool isLoadScreenPlaying = false;
#if AZ_LOADSCREENCOMPONENT_ENABLED
LoadScreenBus::BroadcastResult(isLoadScreenPlaying, &LoadScreenBus::Events::IsPlaying);
#endif // if AZ_LOADSCREENCOMPONENT_ENABLED
// force a black screen as last render command.
// if load screen is playing do not call this draw as it may lead to a crash due to UI loading code getting
// pumped while loading the shaders for this draw.
if (!isLoadScreenPlaying)
{
gEnv->pRenderer->BeginFrame();
gEnv->pRenderer->SetState(GS_BLSRC_SRCALPHA | GS_BLDST_ONEMINUSSRCALPHA | GS_NODEPTHTEST);
gEnv->pRenderer->Draw2dImage(0, 0, 800, 600, -1, 0.0f, 0.0f, 1.0f, 1.0f, 0.f, 0.0f, 0.0f, 0.0f, 1.0, 0.f);
gEnv->pRenderer->EndFrame();
}
// flush any outstanding texture requests
gEnv->pRenderer->FlushPendingTextureTasks();
}
// Clear level entities and prefab instances.
EBUS_EVENT(AzFramework::GameEntityContextRequestBus, ResetGameContext);
if (gEnv->pMovieSystem)
{
gEnv->pMovieSystem->Reset(false, false);
gEnv->pMovieSystem->RemoveAllSequences();
}
// Unload level specific audio binary data.
Audio::SAudioManagerRequestData<Audio::eAMRT_UNLOAD_AFCM_DATA_BY_SCOPE> oAMData(Audio::eADS_LEVEL_SPECIFIC);
Audio::SAudioRequest oAudioRequestData;
oAudioRequestData.nFlags = (Audio::eARF_PRIORITY_HIGH | Audio::eARF_EXECUTE_BLOCKING);
oAudioRequestData.pData = &oAMData;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
// Now unload level specific audio config data.
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_CONTROLS_DATA> oAMData2(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData2;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
Audio::SAudioManagerRequestData<Audio::eAMRT_CLEAR_PRELOADS_DATA> oAMData3(Audio::eADS_LEVEL_SPECIFIC);
oAudioRequestData.pData = &oAMData3;
Audio::AudioSystemRequestBus::Broadcast(&Audio::AudioSystemRequestBus::Events::PushRequestBlocking, oAudioRequestData);
// Reset the camera to (0,0,0) which is the invalid/uninitialised state
CCamera defaultCam;
m_pSystem->SetViewCamera(defaultCam);
OnUnloadComplete(m_lastLevelName.c_str());
AzFramework::RootSpawnableInterface::Get()->ReleaseRootSpawnable();
m_lastLevelName.clear();
GetISystem()->GetIResourceManager()->UnloadLevel();
/*
Force Lua garbage collection before p3DEngine->UnloadLevel() and pRenderer->FreeResources(flags) are called.
p3DEngine->UnloadLevel() will destroy particle emitters even if they're still referenced by Lua objects that are yet to be
collected. (as per comment in 3dEngineLoad.cpp (line 501) - "Force to clean all particles that are left, even if still referenced.").
Then, during the next GC cycle, Lua finally cleans up, the particle emitter smart pointers will be pointing to invalid memory).
Normally the GC step is triggered at the end of this method (by the ESYSTEM_EVENT_LEVEL_POST_UNLOAD event), which is too late
(after the render resources have been purged).
This extra GC step takes a few ms more level unload time, which is a small price for fixing nasty crashes.
If, however, we wanted to claim it back, we could potentially get rid of the GC step that is triggered by
ESYSTEM_EVENT_LEVEL_POST_UNLOAD to break even.
*/
EBUS_EVENT(AZ::ScriptSystemRequestBus, GarbageCollect);
// Delete engine resources
if (p3DEngine)
{
p3DEngine->UnloadLevel();
}
// Force to clean render resources left after deleting all objects and materials.
IRenderer* pRenderer = gEnv->pRenderer;
if (pRenderer)
{
pRenderer->FlushRTCommands(true, true, true);
CryComment("Deleting Render meshes, render resources and flush texture streaming");
// This may also release some of the materials.
int flags = FRR_DELETED_MESHES | FRR_FLUSH_TEXTURESTREAMING | FRR_OBJECTS | FRR_RENDERELEMENTS | FRR_RP_BUFFERS | FRR_POST_EFFECTS;
// Always keep the system resources around in the editor.
// If a level load fails for any reason, then do not unload the system resources, otherwise we will not have any system resources to
// continue rendering the console and debug output text.
if (!gEnv->IsEditor() && !GetLevelLoadFailed())
{
flags |= FRR_SYSTEM_RESOURCES;
}
pRenderer->FreeResources(flags);
CryComment("done");
}
// Perform level unload procedures for the LyShine UI system
if (gEnv && gEnv->pLyShine)
{
gEnv->pLyShine->OnLevelUnload();
}
m_bLevelLoaded = false;
CTimeValue tUnloadTime = gEnv->pTimer->GetAsyncTime() - tBegin;
AZ_TracePrintf("LevelSystem", "UnloadLevel End: %.1f sec\n", tUnloadTime.GetSeconds());
// Must be sent last.
// Cleanup all containers
GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_POST_UNLOAD, 0, 0);
AzFramework::InputChannelRequestBus::Broadcast(&AzFramework::InputChannelRequests::ResetState);
}
void SpawnableLevelSystem::OnRootSpawnableAssigned(
[[maybe_unused]] AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, [[maybe_unused]] uint32_t generation)
{
}
void SpawnableLevelSystem::OnRootSpawnableReleased([[maybe_unused]] uint32_t generation)
{
}
} // namespace LegacyLevelSystem
@@ -0,0 +1,93 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#pragma once
#include "ILevelSystem.h"
#include <AzCore/Console/IConsole.h>
#include <AzFramework/Archive/IArchive.h>
#include <AzFramework/Spawnable/RootSpawnableInterface.h>
namespace LegacyLevelSystem
{
class SpawnableLevelSystem
: public ILevelSystem
, public AzFramework::RootSpawnableNotificationBus::Handler
{
public:
explicit SpawnableLevelSystem(ISystem* pSystem);
~SpawnableLevelSystem() override;
// ILevelSystem
void Release() override;
void AddListener(ILevelSystemListener* pListener) override;
void RemoveListener(ILevelSystemListener* pListener) override;
bool LoadLevel(const char* levelName) override;
void UnloadLevel() override;
bool IsLevelLoaded() override;
const char* GetCurrentLevelName() const override;
// If the level load failed then we need to have a different shutdown procedure vs when a level is naturally unloaded
void SetLevelLoadFailed(bool loadFailed) override;
bool GetLevelLoadFailed() override;
AZ::Data::AssetType GetLevelAssetType() const override;
// The following methods are deprecated from ILevelSystem and will be removed once slice support is removed.
// [LYN-2376] Remove once legacy slice support is removed
void Rescan([[maybe_unused]] const char* levelsFolder) override;
int GetLevelCount() override;
ILevelInfo* GetLevelInfo([[maybe_unused]] int level) override;
ILevelInfo* GetLevelInfo([[maybe_unused]] const char* levelName) override;
private:
void OnRootSpawnableAssigned(AZ::Data::Asset<AzFramework::Spawnable> rootSpawnable, uint32_t generation) override;
void OnRootSpawnableReleased(uint32_t generation) override;
void PrepareNextLevel(const char* levelName);
bool LoadLevelInternal(const char* levelName);
// Methods to notify ILevelSystemListener
void OnPrepareNextLevel(const char* levelName);
void OnLevelNotFound(const char* levelName);
void OnLoadingStart(const char* levelName);
void OnLoadingComplete(const char* levelName);
void OnLoadingError(const char* levelName, const char* error);
void OnLoadingProgress(const char* levelName, int progressAmount);
void OnUnloadComplete(const char* levelName);
void LogLoadingTime();
ISystem* m_pSystem{nullptr};
AZStd::string m_lastLevelName;
float m_fLastLevelLoadTime{0.0f};
float m_fLastTime{0.0f};
bool m_bLevelLoaded{false};
bool m_levelLoadFailed{false};
int m_nLoadedLevelsCount{0};
CTimeValue m_levelLoadStartTime;
AZStd::vector<ILevelSystemListener*> m_listeners;
// Information about the currently-loaded root spawnable, used for tracking loads and unloads.
uint64_t m_rootSpawnableGeneration{0};
AZ::Data::AssetId m_rootSpawnableId{};
};
} // namespace LegacyLevelSystem
+2 -2
View File
@@ -92,8 +92,8 @@ public:
virtual void UnregisterConsoleVariables();
virtual void AddCallback(ILogCallback* pCallback);
virtual void RemoveCallback(ILogCallback* pCallback);
virtual void LogV(const ELogType ineType, int flags, const char* szFormat, va_list args);
virtual void LogV(const ELogType ineType, const char* szFormat, va_list args);
virtual void LogV(ELogType ineType, int flags, const char* szFormat, va_list args);
virtual void LogV(ELogType ineType, const char* szFormat, va_list args);
virtual void Update();
virtual const char* GetModuleFilter();
virtual void FlushAndClose();
+23 -7
View File
@@ -19,6 +19,7 @@
#include "System.h"
#include "MaterialUtils.h"
#include <CryPath.h>
#include <AzFramework/API/ApplicationAPI.h>
#include <AzFramework/IO/FileOperations.h>
#include <AzFramework/Archive/Archive.h>
#include <AzFramework/Archive/INestedArchive.h>
@@ -216,12 +217,20 @@ void CResourceManager::PrepareLevel(const char* sLevelFolder, const char* sLevel
if (g_cvars.archiveVars.nLoadCache)
{
CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME);
size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str());
if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs.
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
// The prefab system doesn't use level.pak
if (!usePrefabSystemForLevels)
{
// Force level.pak from this level in memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
CryPathString levelpak = PathUtil::Make(sLevelFolder, LEVEL_PAK_FILENAME);
size_t nPakFileSize = gEnv->pCryPak->FGetSize(levelpak.c_str());
if (nPakFileSize < LEVEL_PAK_INMEMORY_MAXSIZE) // 10 megs.
{
// Force level.pak from this level in memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
}
}
gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_GPU);
@@ -584,8 +593,15 @@ void CResourceManager::UnloadAllLevelCachePaks(bool bLevelLoadEnd)
{
gEnv->pCryPak->LoadPakToMemory(ENGINE_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
// Force level.pak out of memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
bool usePrefabSystemForLevels = false;
AzFramework::ApplicationRequests::Bus::BroadcastResult(
usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled);
if (!usePrefabSystemForLevels)
{
// Force level.pak out of memory.
gEnv->pCryPak->LoadPakToMemory(LEVEL_PAK_FILENAME, AZ::IO::IArchive::eInMemoryPakLocale_Unload);
}
}
if (!bLevelLoadEnd)
{
+1 -18
View File
@@ -1501,7 +1501,7 @@ bool CSystem::UpdatePreTickBus(int updateFlags, int nPauseMode)
if (maxFPS == 0 && vSync == 0)
{
ILevelSystem* pLvlSys = GetILevelSystem();
const bool inLevel = pLvlSys && pLvlSys->GetCurrentLevel() != 0;
const bool inLevel = pLvlSys && pLvlSys->IsLevelLoaded();
maxFPS = !inLevel || IsPaused() ? 60 : 0;
}
@@ -1791,23 +1791,6 @@ bool CSystem::UpdatePostTickBus(int updateFlags, int nPauseMode)
GetIViewSystem()->Update(min(gEnv->pTimer->GetFrameTime(), 0.1f));
}
if (gEnv->pLyShine)
{
// Tell the UI system the size of the viewport we are rendering to - this drives the
// canvas size for full screen UI canvases. It needs to be set before either pLyShine->Update or
// pLyShine->Render are called. It must match the viewport size that the input system is using.
AZ::Vector2 viewportSize;
viewportSize.SetX(static_cast<float>(gEnv->pRenderer->GetOverlayWidth()));
viewportSize.SetY(static_cast<float>(gEnv->pRenderer->GetOverlayHeight()));
gEnv->pLyShine->SetViewportSize(viewportSize);
bool isUiPaused = gEnv->pTimer->IsTimerPaused(ITimer::ETIMER_UI);
if (!isUiPaused)
{
gEnv->pLyShine->Update(gEnv->pTimer->GetFrameTime(ITimer::ETIMER_UI));
}
}
// Begin occlusion job after setting the correct camera.
gEnv->p3DEngine->PrepareOcclusion(GetViewCamera());
+4 -4
View File
@@ -612,7 +612,7 @@ public:
virtual void SetConfigSpec(ESystemConfigSpec spec, ESystemConfigPlatform platform, bool bClient);
virtual ESystemConfigSpec GetMaxConfigSpec() const;
virtual ESystemConfigPlatform GetConfigPlatform() const;
virtual void SetConfigPlatform(const ESystemConfigPlatform platform);
virtual void SetConfigPlatform(ESystemConfigPlatform platform);
//////////////////////////////////////////////////////////////////////////
virtual int SetThreadState(ESubsystem subsys, bool bActive);
@@ -746,7 +746,7 @@ public:
// interface ISystem -------------------------------------------
virtual IDataProbe* GetIDataProbe() { return m_pDataProbe; };
virtual void SetForceNonDevMode(const bool bValue);
virtual void SetForceNonDevMode(bool bValue);
virtual bool GetForceNonDevMode() const;
virtual bool WasInDevMode() const { return m_bWasInDevMode; };
virtual bool IsDevMode() const { return m_bInDevMode && !GetForceNonDevMode(); }
@@ -759,7 +759,7 @@ public:
}
return (true);
}
virtual void AutoDetectSpec(const bool detectResolution);
virtual void AutoDetectSpec(bool detectResolution);
virtual void AsyncMemcpy(void* dst, const void* src, size_t size, int nFlags, volatile int* sync)
{
@@ -1084,7 +1084,7 @@ public:
}
virtual ESystemGlobalState GetSystemGlobalState(void);
virtual void SetSystemGlobalState(const ESystemGlobalState systemGlobalState);
virtual void SetSystemGlobalState(ESystemGlobalState systemGlobalState);
#if !defined(_RELEASE)
virtual bool IsSavingResourceList() const { return (g_cvars.archiveVars.nSaveLevelResourceList != 0); }
+16 -605
View File
@@ -54,6 +54,7 @@
#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>
@@ -131,6 +132,7 @@
#include "ServiceNetwork.h"
#include "RemoteCommand.h"
#include "LevelSystem/LevelSystem.h"
#include "LevelSystem/SpawnableLevelSystem.h"
#include "ViewSystem/ViewSystem.h"
#include <CrySystemBus.h>
#include <AzCore/Jobs/JobFunction.h>
@@ -310,8 +312,6 @@ namespace
//static int g_sysSpecChanged = false;
const char* g_szLvlResExt = "_LvlRes.txt";
struct SCVarsClientConfigSink
: public ILoadConfigurationEntrySink
{
@@ -1517,27 +1517,16 @@ bool CSystem::InitFileSystem()
m_pUserCallback->OnInitProgress("Initializing File System...");
}
bool bLvlRes = false; // true: all assets since executable start are recorded, false otherwise
// get the DirectInstance FileIOBase which should be the AZ::LocalFileIO
m_env.pFileIO = AZ::IO::FileIOBase::GetDirectInstance();
m_env.pResourceCompilerHelper = nullptr;
#if !defined(_RELEASE)
const ICmdLineArg* pArg = m_pCmdLine->FindArg(eCLAT_Pre, "LvlRes"); // -LvlRes command line option
if (pArg)
{
bLvlRes = true;
}
#endif // !defined(_RELEASE)
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 || bLvlRes)
if (m_bEditor)
{
m_env.pCryPak->RecordFileOpen(AZ::IO::IArchive::RFOM_EngineStartup);
}
@@ -2212,43 +2201,6 @@ public:
using CommandRegisteredHandler = AZ::IConsole::ConsoleCommandRegisteredEvent::Handler;
static inline CommandRegisteredHandler s_commandRegisteredHandler = CommandRegisteredHandler([](AZ::ConsoleFunctorBase* functor) { Visit(functor); });
using CommandInvokedHandler = AZ::ConsoleCommandInvokedEvent::Handler;
static inline CommandInvokedHandler s_commandInvokedHandler = CommandInvokedHandler([]
(
AZStd::string_view command,
const AZ::ConsoleCommandContainer& args,
[[maybe_unused]] AZ::ConsoleFunctorFlags flags,
AZ::ConsoleInvokedFrom invokedFrom
)
{
if (invokedFrom == AZ::ConsoleInvokedFrom::CryBinding)
{
// If a command originated from the cry console, do not echo it back to the cry console
return;
}
AZ::CVarFixedString joinedCommand = AZ::CVarFixedString(command) + " ";
AZ::StringFunc::Join(joinedCommand, args.begin(), args.end(), " ");
gEnv->pConsole->ExecuteString(joinedCommand.c_str(), true);
});
using CommandNotFoundHandler = AZ::DispatchCommandNotFoundEvent::Handler;
static inline CommandNotFoundHandler s_commandNotFoundHandler = CommandNotFoundHandler([]
(
AZStd::string_view command,
const AZ::ConsoleCommandContainer& args,
AZ::ConsoleInvokedFrom invokedFrom
)
{
if (invokedFrom == AZ::ConsoleInvokedFrom::CryBinding)
{
// If a command originated from the cry console, do not echo it back to the cry console
return;
}
AZ::CVarFixedString joinedCommand = AZ::CVarFixedString(command) + " ";
AZ::StringFunc::Join(joinedCommand, args.begin(), args.end(), " ");
gEnv->pConsole->ExecuteString(joinedCommand.c_str(), true);
});
};
// System initialization
@@ -3193,7 +3145,19 @@ AZ_POP_DISABLE_WARNING
//////////////////////////////////////////////////////////////////////////
// LEVEL SYSTEM
m_pLevelSystem = new LegacyLevelSystem::CLevelSystem(this, "levels");
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");
@@ -3276,8 +3240,6 @@ AZ_POP_DISABLE_WARNING
// 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());
AzConsoleToCryConsoleBinder::s_commandInvokedHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetConsoleCommandInvokedEvent());
AzConsoleToCryConsoleBinder::s_commandNotFoundHandler.Connect(AZ::Interface<AZ::IConsole>::Get()->GetDispatchCommandNotFoundEvent());
// final tryflush to be sure that all framework init request have been processed
if (!startupParams.bShaderCacheGen && m_env.pRenderer)
@@ -3384,548 +3346,6 @@ static string ConcatPath(const char* szPart1, const char* szPart2)
return ret;
}
class CLvlRes_base
{
public:
// destructor
virtual ~CLvlRes_base()
{
}
void RegisterAllLevelPaks(const string& sPath)
{
string sPathPattern = ConcatPath(sPath, "*");
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: CLvlRes_base failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
RegisterAllLevelPaks(ConcatPath(sPath, handle.m_filename.data()));
}
}
else if (HasRightExtension(handle.m_filename.data())) // open only the level paks if there is a LvlRes.txt, opening all would be too slow
{
OnPakEntry(sPath, handle.m_filename.data());
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
void Process(const string& sPath)
{
string sPathPattern = ConcatPath(sPath, "*");
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: LvlRes_finalstep failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
Process(ConcatPath(sPath, handle.m_filename.data()));
}
}
else if (HasRightExtension(handle.m_filename.data()))
{
string sFilePath = ConcatPath(sPath, handle.m_filename.data());
gEnv->pLog->Log("CLvlRes_base processing '%s' ...", sFilePath.c_str());
AZ::IO::HandleType fileHandle = gEnv->pCryPak->FOpen(sFilePath.c_str(), "rb");
if (fileHandle != AZ::IO::InvalidHandle)
{
std::vector<char> vBuffer;
size_t len = gEnv->pCryPak->FGetSize(fileHandle);
vBuffer.resize(len + 1);
if (len)
{
if (gEnv->pCryPak->FReadRaw(&vBuffer[0], len, 1, fileHandle) == 1)
{
vBuffer[len] = 0; // end terminator
char* p = &vBuffer[0];
while (*p)
{
while (*p != 0 && *p <= ' ') // jump over whitespace
{
++p;
}
char* pLineStart = p;
while (*p != 0 && *p != 10 && *p != 13) // goto end of line
{
++p;
}
char* pLineEnd = p;
while (*p != 0 && (*p == 10 || *p == 13)) // goto next line with data
{
++p;
}
if (*pLineStart != ';') // if it's not a commented line
{
*pLineEnd = 0;
OnFileEntry(pLineStart); // add line
}
}
}
else
{
gEnv->pLog->LogError("Error: LvlRes_finalstep file open '%s' failed", sFilePath.c_str());
}
}
gEnv->pCryPak->FClose(fileHandle);
}
else
{
gEnv->pLog->LogError("Error: LvlRes_finalstep file open '%s' failed", sFilePath.c_str());
}
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
bool IsFileKnown(const char* szFilePath)
{
string sFilePath = szFilePath;
return m_UniqueFileList.find(sFilePath) != m_UniqueFileList.end();
}
protected: // -------------------------------------------------------------------------
static bool HasRightExtension(const char* szFileName)
{
const char* szLvlResExt = szFileName;
size_t lenName = strlen(szLvlResExt);
static size_t lenLvlExt = strlen(g_szLvlResExt);
if (lenName >= lenLvlExt)
{
szLvlResExt += lenName - lenLvlExt; // "test_LvlRes.txt" -> "_LvlRes.txt"
}
return azstricmp(szLvlResExt, g_szLvlResExt) == 0;
}
// Arguments
// sFilePath - e.g. "game/object/vehices/car01.dds"
void OnFileEntry(const char* szFilePath)
{
string sFilePath = szFilePath;
if (m_UniqueFileList.find(sFilePath) == m_UniqueFileList.end()) // to to file processing only once per file
{
m_UniqueFileList.insert(sFilePath);
ProcessFile(sFilePath);
gEnv->pLog->UpdateLoadingScreen(0);
}
}
virtual void ProcessFile(const string& sFilePath) = 0;
virtual void OnPakEntry([[maybe_unused]] const string& sPath, [[maybe_unused]] const char* szPak) {}
// -----------------------------------------------------------------
std::set<string> m_UniqueFileList; // to removed duplicate files
};
class CLvlRes_finalstep
: public CLvlRes_base
{
public:
// constructor
CLvlRes_finalstep(const char* szPath)
: m_sPath(szPath)
{
assert(szPath);
}
// destructor
virtual ~CLvlRes_finalstep()
{
// free registered paks
std::set<string>::iterator it, end = m_RegisteredPakFiles.end();
for (it = m_RegisteredPakFiles.begin(); it != end; ++it)
{
string sName = *it;
gEnv->pCryPak->ClosePack(sName.c_str());
}
}
// register a pak file so all files within do not become file entries but the pak file becomes
void RegisterPak(const string& sPath, const char* szFile)
{
string sPak = ConcatPath(sPath, szFile);
AZStd::string_view pakView{ sPak.c_str(), sPak.size() };
gEnv->pCryPak->ClosePack(pakView); // so we don't get error for paks that were already opened
if (!gEnv->pCryPak->OpenPack(pakView))
{
CryLog("RegisterPak '%s' failed - file not present?", sPak.c_str());
return;
}
enum
{
nMaxPath = 0x800
};
char szAbsPathBuf[nMaxPath];
const char* szAbsPath = gEnv->pCryPak->AdjustFileName({ sPak.c_str(), sPak.size() }, szAbsPathBuf, AZ_ARRAY_SIZE(szAbsPathBuf), 0);
// string sAbsPath = PathUtil::RemoveSlash(PathUtil::GetPath(szAbsPath));
// debug
CryLog("RegisterPak '%s'", szAbsPath);
m_RegisteredPakFiles.insert(string(szAbsPath));
OnFileEntry(sPak); // include pak as file entry
}
// finds a specific file
static AZ::IO::ArchiveFileIterator FindFile(const char* szFilePath, const char* szFile)
{
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(szFilePath);
if (!handle)
{
return {};
}
do
{
if (azstricmp(handle.m_filename.data(), szFile) == 0)
{
gEnv->pCryPak->FindClose(handle);
return handle;
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
return {};
}
// slow but safe (to correct path and file name upper/lower case to the existing files)
// some code might rely on the case (e.g. CVarGroup creation) so it's better to correct the case
static void CorrectCaseInPlace(char* szFilePath)
{
// required for FindFirst, TODO: investigate as this seems wrong behavior
{
// jump over "Game"
while (*szFilePath != '/' && *szFilePath != '\\' && *szFilePath != 0)
{
++szFilePath;
}
// jump over "/"
if (*szFilePath != 0)
{
++szFilePath;
}
}
char* szFile = szFilePath, * p = szFilePath;
for (;; )
{
if (*p == '/' || *p == '\\' || *p == 0)
{
char cOldChar = *p;
*p = 0; // create zero termination
auto fileIterator = FindFile(szFilePath, szFile);
if (fileIterator)
{
assert(strlen(szFile) == fileIterator.m_filename.size());
}
*p = cOldChar; // get back the old separator
if (!fileIterator)
{
return;
}
fileIterator.m_filename.copy(szFile, fileIterator.m_filename.size());
if (*p == 0)
{
break;
}
++p;
szFile = p;
}
else
{
++p;
}
}
}
virtual void ProcessFile(const string& _sFilePath)
{
string sFilePath = _sFilePath;
CorrectCaseInPlace((char*)&sFilePath[0]);
gEnv->pLog->LogWithType(ILog::eAlways, "LvlRes: %s", sFilePath.c_str());
CCryFile file;
std::vector<char> data;
if (!file.Open(sFilePath.c_str(), "rb"))
{
gEnv->pLog->LogError("ERROR: failed to open '%s'", sFilePath.c_str()); // pak not opened ?
return;
}
if (IsInRegisteredPak(file.GetHandle()))
{
return; // then don't process as we include the pak
}
// Save this file in target folder.
string trgFilename = PathUtil::Make(m_sPath, sFilePath);
int fsize = file.GetLength();
size_t len = file.GetLength();
if (fsize > (int)data.size())
{
data.resize(fsize + 16);
}
// Read data.
file.ReadRaw(&data[0], fsize);
// Save this data to target file.
string trgFileDir = PathUtil::ToDosPath(PathUtil::RemoveSlash(PathUtil::GetPath(trgFilename)));
gEnv->pFileIO->CreatePath(trgFileDir); // ensure path exists
// Create target file
FILE* trgFile = nullptr;
azfopen(&trgFile, trgFilename, "wb");
if (trgFile)
{
fwrite(&data[0], fsize, 1, trgFile);
fclose(trgFile);
}
else
{
gEnv->pLog->LogError("ERROR: failed to write '%s' (write protected/disk full/rights)", trgFilename.c_str());
assert(0);
}
}
bool IsInRegisteredPak(AZ::IO::HandleType fileHandle)
{
const char* szPak = gEnv->pCryPak->GetFileArchivePath(fileHandle);
if (!szPak)
{
return false; // outside pak
}
bool bInsideRegisteredPak = m_RegisteredPakFiles.find(szPak) != m_RegisteredPakFiles.end();
return bInsideRegisteredPak;
}
virtual void OnPakEntry(const string& sPath, [[maybe_unused]] const char* szPak)
{
RegisterPak(sPath, "level.pak");
RegisterPak(sPath, "levelmm.pak");
}
// -------------------------------------------------------------------------------
string m_sPath; // directory path to store the assets e.g. "c:\temp\Out"
std::set<string> m_RegisteredPakFiles; // abs path to pak files we registered e.g. "c:\MasterCD\game\GameData.pak", to avoid processing files inside these pak files - the ones we anyway want to include
};
class CLvlRes_findunused
: public CLvlRes_base
{
public:
virtual void ProcessFile([[maybe_unused]] const string& sFilePath)
{
}
};
static void LvlRes_finalstep(IConsoleCmdArgs* pParams)
{
assert(pParams);
uint32 dwCnt = pParams->GetArgCount();
if (dwCnt != 2)
{
gEnv->pLog->LogWithType(ILog::eError, "ERROR: sys_LvlRes_finalstep requires destination path as parameter");
return;
}
const char* szPath = pParams->GetArg(1);
assert(szPath);
gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_LvlRes_finalstep %s ...", szPath);
// open console
gEnv->pConsole->ShowConsole(true);
CLvlRes_finalstep sink(szPath);
sink.RegisterPak("@assets@", "GameData.pak");
sink.RegisterPak("@assets@", "Shaders.pak");
sink.RegisterAllLevelPaks("levels");
sink.Process("levels");
}
static void _LvlRes_findunused_recursive(CLvlRes_findunused& sink, const string& sPath,
uint32& dwUnused, uint32& dwAll)
{
string sPathPattern = ConcatPath(sPath, "*");
// ignore some directories
if (azstricmp(sPath.c_str(), "Shaders") == 0
|| azstricmp(sPath.c_str(), "ScreenShots") == 0
|| azstricmp(sPath.c_str(), "Scripts") == 0
|| azstricmp(sPath.c_str(), "Config") == 0
|| azstricmp(sPath.c_str(), "LowSpec") == 0)
{
return;
}
// gEnv->pLog->Log("_LvlRes_findunused_recursive '%s'",sPath.c_str());
AZ::IO::ArchiveFileIterator handle = gEnv->pCryPak->FindFirst(sPathPattern.c_str());
if (!handle)
{
gEnv->pLog->LogError("ERROR: _LvlRes_findunused_recursive failed '%s'", sPathPattern.c_str());
return;
}
do
{
if ((handle.m_fileDesc.nAttrib & AZ::IO::FileDesc::Attribute::Subdirectory) == AZ::IO::FileDesc::Attribute::Subdirectory)
{
if (handle.m_filename != "." && handle.m_filename != "..")
{
_LvlRes_findunused_recursive(sink, ConcatPath(sPath, handle.m_filename.data()), dwUnused, dwAll);
}
}
else
{
string sFilePath = CryStringUtils::ToLower(ConcatPath(sPath, handle.m_filename.data()));
enum
{
nMaxPath = 0x800
};
char szAbsPathBuf[nMaxPath];
gEnv->pCryPak->AdjustFileName(sFilePath.c_str(), szAbsPathBuf, AZ_ARRAY_SIZE(szAbsPathBuf), 0);
if (!sink.IsFileKnown(szAbsPathBuf))
{
gEnv->pLog->LogWithType(IMiniLog::eAlways, "%d, %s", (uint32)handle.m_fileDesc.nSize, szAbsPathBuf);
++dwUnused;
}
++dwAll;
}
} while (handle = gEnv->pCryPak->FindNext(handle));
gEnv->pCryPak->FindClose(handle);
}
static void LvlRes_findunused([[maybe_unused]] IConsoleCmdArgs* pParams)
{
assert(pParams);
gEnv->pLog->LogWithType(ILog::eInputResponse, "sys_LvlRes_findunused ...");
// open console
gEnv->pConsole->ShowConsole(true);
CLvlRes_findunused sink;
sink.RegisterAllLevelPaks("levels");
sink.Process("levels");
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
gEnv->pLog->LogWithType(ILog::eInputResponse, "Assets not used by the existing LvlRes data:");
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
char rootpath[_MAX_PATH];
AZ::Utils::GetExecutableDirectory(rootpath, _MAX_PATH);
gEnv->pLog->LogWithType(ILog::eInputResponse, "Folder: %s", rootpath);
uint32 dwUnused = 0, dwAll = 0;
string unused;
_LvlRes_findunused_recursive(sink, unused, dwUnused, dwAll);
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
gEnv->pLog->LogWithType(ILog::eInputResponse, "Unused assets: %d/%d", dwUnused, dwAll);
gEnv->pLog->LogWithType(ILog::eInputResponse, " ");
}
static void ScreenshotCmd(IConsoleCmdArgs* pParams)
{
assert(pParams);
@@ -4628,15 +4048,9 @@ void CSystem::CreateSystemVars()
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_STRING("capture_file_format", "jpg", 0, "Specifies file format of captured files (jpg, tga, tif).");
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'.");
REGISTER_INT("capture_buffer", 0, 0,
"Buffer to capture when capture_frames is enabled.\n"
"0=Color\n"
"1=Color with Alpha (requires capture_file_format=tga)");
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);
@@ -4645,7 +4059,6 @@ void CSystem::CreateSystemVars()
"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");
@@ -4656,8 +4069,6 @@ void CSystem::CreateSystemVars()
"e.g. Screenshot beach scene with shark\n"
"Usage: Screenshot <annotation text>");
REGISTER_COMMAND("sys_LvlRes_finalstep", &LvlRes_finalstep, 0, "to combine all recorded level resources and create final stripped build (pass directory name as parameter)");
REGISTER_COMMAND("sys_LvlRes_findunused", &LvlRes_findunused, 0, "find unused level resources");
/*
// experimental feature? - needs to be created very early
m_sys_filecache = REGISTER_INT("sys_FileCache",0,0,
-15
View File
@@ -353,15 +353,6 @@ void CSystem::RenderEnd([[maybe_unused]] bool bRenderStats, bool bMainWindow)
if (!gEnv->pSystem->GetILevelSystem() || !gEnv->pSystem->GetILevelSystem()->IsLevelLoaded())
{
IConsole* console = GetIConsole();
ILyShine* lyShine = gEnv->pLyShine;
//Normally the UI is drawn as part of the scene so it can properly render once per eye in VR
//We only want to draw here if there is no level loaded. This way the user can see loading
// UI and other information before the level is loaded.
if (lyShine != nullptr)
{
lyShine->Render();
}
//Same goes for the console. When no level is loaded, it's okay to render it outside of the renderer
//so that users can load maps or change settings.
@@ -390,12 +381,6 @@ void CSystem::RenderEnd([[maybe_unused]] bool bRenderStats, bool bMainWindow)
void CSystem::OnScene3DEnd()
{
// Render UI Canvas
if (m_bDrawUI && gEnv->pLyShine)
{
gEnv->pLyShine->Render();
}
//Render Console
if (m_bDrawConsole && gEnv->pConsole)
{
@@ -20,7 +20,11 @@ namespace UnitTest
: public ::testing::Test
{};
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_InverserSqrt_HasAtLeast22BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, InverserSqrt_HasAtLeast22BitsOfAccuracy)
#endif
{
float testFloat(0.336950600);
const float result = isqrt_safe_tpl(testFloat * testFloat);
@@ -28,7 +32,11 @@ namespace UnitTest
EXPECT_NEAR(2.96779, result, epsilon);
}
#if AZ_TRAIT_DISABLE_FAILED_MATH_TESTS
TEST_F(CryMathTestFixture, DISABLED_SimdSqrt_HasAtLeast23BitsOfAccuracy)
#else
TEST_F(CryMathTestFixture, SimdSqrt_HasAtLeast23BitsOfAccuracy)
#endif
{
float testFloat(3434.34839439);
const float result = sqrt_tpl(testFloat);
@@ -55,55 +55,6 @@ namespace CryPakUnitTests
}
};
TEST_F(Integ_CryPakUnitTests, TestCryPakArchiveContainingLevels)
{
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
ASSERT_NE(nullptr, fileIo);
constexpr const char* testPakPath = "@usercache@/archivecontainerlevel.pak";
char resolvedArchivePath[AZ_MAX_PATH_LEN] = { 0 };
EXPECT_TRUE(fileIo->ResolvePath(testPakPath, resolvedArchivePath, AZ_MAX_PATH_LEN));
AZ::IO::IArchive* pak = gEnv->pCryPak;
ASSERT_NE(nullptr, pak);
// delete test files in case they already exist
pak->ClosePack(testPakPath);
fileIo->Remove(testPakPath);
ILevelSystem* levelSystem = gEnv->pSystem->GetILevelSystem();
EXPECT_NE(nullptr, levelSystem);
// ------------ Create an archive with a dummy level in it ------------
AZStd::intrusive_ptr<AZ::IO::INestedArchive> pArchive = pak->OpenArchive(testPakPath, nullptr, AZ::IO::INestedArchive::FLAGS_CREATE_NEW);
EXPECT_NE(nullptr, pArchive);
const char levelInfoFile[] = "levelInfo.xml";
AZStd::string relativeLevelPakPath = AZStd::string::format("levels/dummy/%s", ILevelSystem::LevelPakName);
AZStd::string relativeLevelInfoPath = AZStd::string::format("levels/dummy/%s", levelInfoFile);
EXPECT_EQ(0, pArchive->UpdateFile(relativeLevelPakPath.c_str(), const_cast<char*>("test"), 4, AZ::IO::INestedArchive::METHOD_COMPRESS, AZ::IO::INestedArchive::LEVEL_BEST));
EXPECT_EQ(0, pArchive->UpdateFile(relativeLevelInfoPath.c_str(), const_cast<char*>("test"), 4, AZ::IO::INestedArchive::METHOD_COMPRESS, AZ::IO::INestedArchive::LEVEL_BEST));
pArchive.reset();
EXPECT_TRUE(IsPackValid(testPakPath));
AZStd::fixed_string<AZ::IO::IArchive::MaxPath> fullLevelPakPath;
bool addLevel = true;
EXPECT_TRUE(pak->OpenPack("@assets@", resolvedArchivePath, AZ::IO::IArchive::FLAGS_LEVEL_PAK_INSIDE_PAK, nullptr, &fullLevelPakPath, addLevel));
ILevelInfo* levelInfo = nullptr;
// Since the archive was open, we should be able to find the level "dummy"
levelInfo = levelSystem->GetLevelInfo("dummy");
EXPECT_NE(nullptr, levelInfo);
EXPECT_TRUE(pak->ClosePack(resolvedArchivePath));
// After closing the archive we should not be able to find the level "dummy"
levelInfo = levelSystem->GetLevelInfo("dummy");
EXPECT_EQ(nullptr, levelInfo);
}
TEST_F(Integ_CryPakUnitTests, TestCryPakModTime)
{
AZ::IO::FileIOBase* fileIo = AZ::IO::FileIOBase::GetInstance();
@@ -595,7 +595,7 @@ void CViewSystem::UpdateSoundListeners()
}
//////////////////////////////////////////////////////////////////
void CViewSystem::OnLoadingStart([[maybe_unused]] ILevelInfo* pLevel)
void CViewSystem::OnLoadingStart([[maybe_unused]] const char* levelName)
{
//If the level is being restarted (IsSerializingFile() == 1)
//views should not be cleared, because the main view (player one) won't be recreated in this case
@@ -609,7 +609,7 @@ void CViewSystem::OnLoadingStart([[maybe_unused]] ILevelInfo* pLevel)
}
/////////////////////////////////////////////////////////////////////
void CViewSystem::OnUnloadComplete([[maybe_unused]] ILevel* pLevel)
void CViewSystem::OnUnloadComplete([[maybe_unused]] const char* levelName)
{
bool shouldClearViews = gEnv->pSystem ? (gEnv->pSystem->IsSerializingFile() != 1) : false;
@@ -85,11 +85,11 @@ public:
// ILevelSystemListener
virtual void OnLevelNotFound([[maybe_unused]] const char* levelName) {};
virtual void OnLoadingStart(ILevelInfo* pLevel);
virtual void OnLoadingComplete([[maybe_unused]] ILevel* pLevel) {};
virtual void OnLoadingError([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] const char* error) {};
virtual void OnLoadingProgress([[maybe_unused]] ILevelInfo* pLevel, [[maybe_unused]] int progressAmount) {};
virtual void OnUnloadComplete(ILevel* pLevel);
virtual void OnLoadingStart([[maybe_unused]] const char* levelName);
virtual void OnLoadingComplete([[maybe_unused]] const char* levelName){};
virtual void OnLoadingError([[maybe_unused]] const char* levelName, [[maybe_unused]] const char* error){};
virtual void OnLoadingProgress([[maybe_unused]] const char* levelName, [[maybe_unused]] int progressAmount){};
virtual void OnUnloadComplete([[maybe_unused]] const char* levelName);
//~ILevelSystemListener
CViewSystem(ISystem* pSystem);
+4 -4
View File
@@ -170,7 +170,7 @@ public:
virtual void SetScrollMax(int value);
virtual void AddOutputPrintSink(IOutputPrintSink* inpSink);
virtual void RemoveOutputPrintSink(IOutputPrintSink* inpSink);
virtual void ShowConsole(bool show, const int iRequestScrollMax = -1);
virtual void ShowConsole(bool show, int iRequestScrollMax = -1);
virtual void DumpCVars(ICVarDumpSink* pCallback, unsigned int nFlagsFilter = 0);
virtual void DumpKeyBinds(IKeyBindDumpSink* pCallback);
virtual void CreateKeyBind(const char* sCmd, const char* sRes);
@@ -178,7 +178,7 @@ public:
virtual void SetImage(ITexture* pImage, bool bDeleteCurrent);
virtual inline ITexture* GetImage() { return m_pImage; }
virtual void StaticBackground(bool bStatic) { m_bStaticBackground = bStatic; }
virtual bool GetLineNo(const int indwLineNo, char* outszBuffer, const int indwBufferSize) const;
virtual bool GetLineNo(int indwLineNo, char* outszBuffer, int indwBufferSize) const;
virtual int GetLineCount() const;
virtual ICVar* GetCVar(const char* name);
virtual char* GetVariable(const char* szVarName, const char* szFileName, const char* def_val);
@@ -192,7 +192,7 @@ public:
virtual bool AddCommand(const char* sCommand, ConsoleCommandFunc func, int nFlags = 0, const char* sHelp = NULL);
virtual bool AddCommand(const char* sName, const char* sScriptFunc, int nFlags = 0, const char* sHelp = NULL);
virtual void RemoveCommand(const char* sName);
virtual void ExecuteString(const char* command, const bool bSilentMode, const bool bDeferExecution = false);
virtual void ExecuteString(const char* command, bool bSilentMode, bool bDeferExecution = false);
virtual void ExecuteConsoleCommand(const char* command) override;
virtual void ResetCVarsToDefaults() override;
virtual void Exit(const char* command, ...) PRINTF_PARAMS(2, 3);
@@ -218,7 +218,7 @@ public:
virtual void SetLoadingImage(const char* szFilename);
virtual void AddConsoleVarSink(IConsoleVarSink* pSink);
virtual void RemoveConsoleVarSink(IConsoleVarSink* pSink);
virtual const char* GetHistoryElement(const bool bUpOrDown);
virtual const char* GetHistoryElement(bool bUpOrDown);
virtual void AddCommandToHistory(const char* szCommand);
virtual void SetInputLine(const char* szLine);
virtual void LoadConfigVar(const char* sVariable, const char* sValue);
+16 -16
View File
@@ -221,7 +221,7 @@ public:
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
stack_string s;
s.Format("%g", f);
@@ -235,7 +235,7 @@ public:
Set(s.c_str());
}
virtual void Set(const int i)
virtual void Set(int i)
{
stack_string s;
s.Format("%d", i);
@@ -289,11 +289,11 @@ public:
Set(nValue);
}
virtual void Set(const float f)
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(const int i)
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -353,15 +353,15 @@ public:
Set(nValue);
}
virtual void Set(const float f)
virtual void Set(float f)
{
Set((int)f);
}
virtual void Set(const int i)
virtual void Set(int i)
{
Set((int64)i);
}
virtual void Set(const int64 i)
virtual void Set(int64 i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -439,7 +439,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -459,7 +459,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -542,7 +542,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if ((int)f == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -560,7 +560,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if (i == m_iValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -639,7 +639,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
if (f == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -657,7 +657,7 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const int i)
virtual void Set(int i)
{
if ((float)i == m_fValue && (m_nFlags & VF_ALWAYSONCHANGE) == 0)
{
@@ -742,13 +742,13 @@ public:
m_pConsole->OnAfterVarChange(this);
}
}
virtual void Set(const float f)
virtual void Set(float f)
{
stack_string s;
s.Format("%g", f);
Set(s.c_str());
}
virtual void Set(const int i)
virtual void Set(int i)
{
stack_string s;
s.Format("%d", i);
@@ -792,7 +792,7 @@ public:
virtual void DebugLog(const int iExpectedValue, const ICVar::EConsoleLogMode mode) const;
virtual void Set(const int i);
virtual void Set(int i);
// ConsoleVarFunc ------------------------------------------------------------------------------------
@@ -178,6 +178,8 @@ set(FILES
LZ4Decompressor.cpp
LevelSystem/LevelSystem.cpp
LevelSystem/LevelSystem.h
LevelSystem/SpawnableLevelSystem.cpp
LevelSystem/SpawnableLevelSystem.h
ViewSystem/DebugCamera.cpp
ViewSystem/DebugCamera.h
ViewSystem/View.cpp