Initial commit

This commit is contained in:
alexpete
2021-03-05 11:26:34 -08:00
commit a10351f38d
27091 changed files with 5521199 additions and 0 deletions
+265
View File
@@ -0,0 +1,265 @@
#
# 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.
#
ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Platform/${PAL_PLATFORM_NAME})
include(${pal_dir}/LauncherUnified_traits_${PAL_PLATFORM_NAME_LOWERCASE}.cmake)
ly_add_target(
NAME Launcher.Static STATIC
NAMESPACE AZ
FILES_CMAKE
launcher_files.cmake
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
${pal_dir}
BUILD_DEPENDENCIES
PUBLIC
AZ::AzCore
AZ::AzGameFramework
Legacy::CryCommon
)
ly_add_target(
NAME Launcher.Game.Static STATIC
NAMESPACE AZ
FILES_CMAKE
launcher_game_files.cmake
${pal_dir}/launcher_game_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzGameFramework
Legacy::CryCommon
)
if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
ly_add_target(
NAME Launcher.Server.Static STATIC
NAMESPACE AZ
FILES_CMAKE
launcher_server_files.cmake
INCLUDE_DIRECTORIES
PRIVATE
.
BUILD_DEPENDENCIES
PRIVATE
AZ::AzCore
AZ::AzGameFramework
Legacy::CryCommon
)
endif()
foreach(project ${LY_PROJECTS})
################################################################################
# Monolithic game
################################################################################
if(LY_MONOLITHIC_GAME)
# In the monolithic case, we need to register the gem modules, to do so we will generate a StaticModules.inl
# file from StaticModules.in
get_property(game_gem_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_${project}.GameLauncher)
unset(extern_module_declarations)
unset(module_invocations)
foreach(game_gem_dependency ${game_gem_dependencies})
# To match the convention on how gems targets vs gem modules are named, we remove the "Gem::" from prefix
# and remove the ".Static" from the suffix
string(REGEX REPLACE "^Gem::" "Gem_" game_gem_dependency ${game_gem_dependency})
# Replace "." with "_"
string(REPLACE "." "_" game_gem_dependency ${game_gem_dependency})
string(APPEND extern_module_declarations "extern \"C\" AZ::Module* CreateModuleClass_${game_gem_dependency}();\n")
string(APPEND module_invocations " modulesOut.push_back(CreateModuleClass_${game_gem_dependency}());\n")
endforeach()
configure_file(StaticModules.in
${CMAKE_CURRENT_BINARY_DIR}/${project}.GameLauncher/Includes/StaticModules.inl
)
set(game_build_dependencies
${game_gem_dependencies}
Legacy::CrySystem
Legacy::CryFont
Legacy::Cry3DEngine
Legacy::CryNetwork
)
if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
get_property(server_gem_dependencies GLOBAL PROPERTY LY_DELAYED_DEPENDENCIES_${project}.ServerLauncher)
unset(extern_module_declarations)
unset(module_invocations)
foreach(server_gem_dependency ${server_gem_dependencies})
# To match the convention on how gems targets vs gem modules are named, we remove the "Gem::" from prefix
# and remove the ".Static" from the suffix
string(REGEX REPLACE "^Gem::" "Gem_" server_gem_dependency ${server_gem_dependency})
# Replace "." with "_"
string(REPLACE "." "_" server_gem_dependency ${server_gem_dependency})
string(APPEND extern_module_declarations "extern \"C\" AZ::Module* CreateModuleClass_${server_gem_dependency}();\n")
string(APPEND module_invocations " modulesOut.push_back(CreateModuleClass_${server_gem_dependency}());\n")
endforeach()
configure_file(StaticModules.in
${CMAKE_CURRENT_BINARY_DIR}/${project}.ServerLauncher/Includes/StaticModules.inl
)
set(server_build_dependencies
${game_gem_dependencies}
Legacy::CrySystem
Legacy::CryFont
Legacy::Cry3DEngine
Legacy::CryNetwork
)
endif()
else()
set(game_runtime_dependencies
Legacy::CrySystem
Legacy::CryFont
Legacy::Cry3DEngine
Legacy::CryNetwork
)
if(PAL_TRAIT_BUILD_SERVER_SUPPORTED AND NOT LY_MONOLITHIC_GAME) # Only Atom is supported in monolithic builds
set(server_runtime_dependencies
Legacy::CryRenderNULL
)
endif()
endif()
################################################################################
# Game
################################################################################
ly_add_target(
NAME ${project}.GameLauncher ${PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE}
NAMESPACE AZ
FILES_CMAKE
launcher_project_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/launcher_project_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
COMPILE_DEFINITIONS
PRIVATE
# Adds the name of the project/game
LY_GAME_PROJECT_NAME="${project}"
# Adds the ${project}_GameLauncher target as a define so for the Settings Registry to use
# when loading .setreg file specializations
# This is needed so that only gems for the project game launcher are loaded
LY_CMAKE_TARGET="${project}_GameLauncher"
INCLUDE_DIRECTORIES
PRIVATE
.
${CMAKE_CURRENT_BINARY_DIR}/${project}.GameLauncher/Includes # required for StaticModules.inl
BUILD_DEPENDENCIES
PRIVATE
AZ::Launcher.Static
AZ::Launcher.Game.Static
${game_build_dependencies}
RUNTIME_DEPENDENCIES
${game_runtime_dependencies}
)
# Needs to be set manually after ly_add_target to prevent the default location overriding it
set_target_properties(${project}.GameLauncher
PROPERTIES
FOLDER ${project}
)
################################################################################
# Server
################################################################################
if(PAL_TRAIT_BUILD_SERVER_SUPPORTED)
get_property(server_projects GLOBAL PROPERTY LY_LAUNCHER_SERVER_PROJECTS)
if(${project} IN_LIST server_projects)
ly_add_target(
NAME ${project}.ServerLauncher APPLICATION
NAMESPACE AZ
FILES_CMAKE
launcher_project_files.cmake
PLATFORM_INCLUDE_FILES
${pal_dir}/launcher_project_${PAL_PLATFORM_NAME_LOWERCASE}.cmake
COMPILE_DEFINITIONS
PRIVATE
# Adds the name of the project/game
LY_GAME_PROJECT_NAME="${project}"
# Adds the ${project}_ServerLauncher target as a define so for the Settings Registry to use
# when loading .setreg file specializations
# This is needed so that only gems for the project server launcher are loaded
LY_CMAKE_TARGET="${project}_ServerLauncher"
INCLUDE_DIRECTORIES
PRIVATE
.
${CMAKE_CURRENT_BINARY_DIR}/${project}.ServerLauncher/Includes # required for StaticModules.inl
BUILD_DEPENDENCIES
PRIVATE
AZ::Launcher.Static
AZ::Launcher.Server.Static
${server_build_dependencies}
RUNTIME_DEPENDENCIES
${server_runtime_dependencies}
)
# Needs to be set manually after ly_add_target to prevent the default location overriding it
set_target_properties(${project}.ServerLauncher
PROPERTIES
FOLDER ${project}
)
endif()
endif()
endforeach()
################################################################################
# Tests
################################################################################
if(PAL_TRAIT_BUILD_TESTS_SUPPORTED AND PAL_TRAIT_BUILD_HOST_TOOLS)
ly_add_target(
NAME Launcher.Tests ${PAL_TRAIT_TEST_TARGET_TYPE}
NAMESPACE AZ
FILES_CMAKE
launcher_test_files.cmake
COMPILE_DEFINITIONS
PRIVATE
LY_CMAKE_TARGET="Launcher_Tests"
INCLUDE_DIRECTORIES
PRIVATE
.
${pal_dir}
BUILD_DEPENDENCIES
PRIVATE
AZ::AzTest
AZ::Launcher.Static
)
ly_add_googletest(
NAME AZ::Launcher.Tests
)
endif()
+31
View File
@@ -0,0 +1,31 @@
/*
* 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 <AzCore/std/string/string_view.h>
namespace LumberyardLauncher
{
bool WaitForAssetProcessorConnect()
{
return true;
}
bool IsDedicatedServer()
{
return false;
}
const char* GetLogFilename()
{
return "@log@/Game.log";
}
}
+795
View File
@@ -0,0 +1,795 @@
/*
* 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 <Launcher.h>
#include <AzCore/Casting/numeric_cast.h>
#include <AzCore/Debug/Trace.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/IO/SystemFile.h>
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
#include <AzCore/Console/IConsole.h>
#include <AzCore/std/smart_ptr/make_shared.h>
#include <AzFramework/StringFunc/StringFunc.h>
#include <AzFramework/Asset/AssetSystemBus.h>
#include <AzFramework/IO/RemoteStorageDrive.h>
#include <AzGameFramework/Application/GameApplication.h>
#include <CryLibrary.h>
#include <IConsole.h>
#include <ITimer.h>
#include <LegacyAllocator.h>
#include <ParseEngineConfig.h>
#include <Launcher_Traits_Platform.h>
#if defined(AZ_MONOLITHIC_BUILD)
extern "C" void CreateStaticModules(AZStd::vector<AZ::Module*>& modulesOut);
#endif // defined(AZ_MONOLITHIC_BUILD)
// Add the "REMOTE_ASSET_PROCESSOR" define except in release
// this makes it so that asset processor functions. Without this, all assets must be present and on local media
// with this, the asset processor can be used to remotely process assets.
#if !defined(_RELEASE)
# define REMOTE_ASSET_PROCESSOR
#endif
namespace
{
#if AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE
// mimics AZ::DynamicModuleHandle but uses CryLibrary under the hood,
// which is necessary to properly load legacy Cry libraries on some platforms
class DynamicModuleHandle
{
public:
AZ_CLASS_ALLOCATOR(DynamicModuleHandle, AZ::OSAllocator, 0)
static AZStd::unique_ptr<DynamicModuleHandle> Create(const char* fullFileName)
{
return AZStd::unique_ptr<DynamicModuleHandle>(aznew DynamicModuleHandle(fullFileName));
}
DynamicModuleHandle(const DynamicModuleHandle&) = delete;
DynamicModuleHandle& operator=(const DynamicModuleHandle&) = delete;
~DynamicModuleHandle()
{
Unload();
}
// argument is strictly to match the API of AZ::DynamicModuleHandle
bool Load(bool unused)
{
AZ_UNUSED(unused);
if (IsLoaded())
{
return true;
}
m_moduleHandle = CryLoadLibrary(m_fileName.c_str());
return IsLoaded();
}
bool Unload()
{
if (!IsLoaded())
{
return false;
}
return CryFreeLibrary(m_moduleHandle);
}
bool IsLoaded() const
{
return m_moduleHandle != nullptr;
}
const AZ::OSString& GetFilename() const
{
return m_fileName;
}
template<typename Function>
Function GetFunction(const char* functionName) const
{
if (IsLoaded())
{
return reinterpret_cast<Function>(CryGetProcAddress(m_moduleHandle, functionName));
}
else
{
return nullptr;
}
}
private:
DynamicModuleHandle(const char* fileFullName)
: m_fileName()
, m_moduleHandle(nullptr)
{
m_fileName = AZ::OSString::format("%s%s%s",
CrySharedLibraryPrefix, fileFullName, CrySharedLibraryExtension);
}
AZ::OSString m_fileName;
HMODULE m_moduleHandle;
};
#else
// mimics AZ::DynamicModuleHandle but also calls InjectEnvironmentFunction on
// the loaded module which is necessary to properly load legacy Cry libraries
class DynamicModuleHandle
{
public:
AZ_CLASS_ALLOCATOR(DynamicModuleHandle, AZ::OSAllocator, 0);
static AZStd::unique_ptr<DynamicModuleHandle> Create(const char* fullFileName)
{
return AZStd::unique_ptr<DynamicModuleHandle>(aznew DynamicModuleHandle(fullFileName));
}
bool Load(bool isInitializeFunctionRequired)
{
const bool loaded = m_moduleHandle->Load(isInitializeFunctionRequired);
if (loaded)
{
// We need to inject the environment first thing so that allocators are available immediately
InjectEnvironmentFunction injectEnv = GetFunction<InjectEnvironmentFunction>(INJECT_ENVIRONMENT_FUNCTION);
if (injectEnv)
{
auto env = AZ::Environment::GetInstance();
injectEnv(env);
}
}
return loaded;
}
bool Unload()
{
bool unloaded = m_moduleHandle->Unload();
if (unloaded)
{
DetachEnvironmentFunction detachEnv = GetFunction<DetachEnvironmentFunction>(DETACH_ENVIRONMENT_FUNCTION);
if (detachEnv)
{
detachEnv();
}
}
return unloaded;
}
template<typename Function>
Function GetFunction(const char* functionName) const
{
return m_moduleHandle->GetFunction<Function>(functionName);
}
private:
DynamicModuleHandle(const char* fileFullName)
: m_moduleHandle(AZ::DynamicModuleHandle::Create(fileFullName))
{
}
AZStd::unique_ptr<AZ::DynamicModuleHandle> m_moduleHandle;
};
#endif // AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE
void RunMainLoop(AzGameFramework::GameApplication& gameApplication)
{
// Ideally we'd just call GameApplication::RunMainLoop instead, but
// we'd have to stop calling ISystem::UpdatePreTickBus / PostTickBus
// directly, and instead have something subscribe to the TickBus in
// order to call them, using order ComponentTickBus::TICK_FIRST - 1
// and ComponentTickBus::TICK_LAST + 1 to ensure they get called at
// the same time as they do now. Also, we'd need to pass a function
// pointer to AzGameFramework::GameApplication::MainLoop that would
// be used to call ITimer::GetFrameTime (unless we could also shift
// our frame time to be managed by AzGameFramework::GameApplication
// instead, which probably isn't going to happen anytime soon given
// how many things depend on the ITimer interface).
bool continueRunning = true;
ISystem* system = gEnv ? gEnv->pSystem : nullptr;
while (continueRunning)
{
// Pump the system event loop
gameApplication.PumpSystemEventLoopUntilEmpty();
// Update the AzFramework system tick bus
gameApplication.TickSystem();
// Pre-update CrySystem
if (system)
{
system->UpdatePreTickBus();
}
// Update the AzFramework application tick bus
gameApplication.Tick(gEnv->pTimer->GetFrameTime());
// Post-update CrySystem
if (system)
{
system->UpdatePostTickBus();
}
// Check for quit requests
continueRunning = !gameApplication.WasExitMainLoopRequested() && continueRunning;
}
}
}
namespace LumberyardLauncher
{
AZ_CVAR(bool, bg_ConnectToAssetProcessor, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "If true, the process will launch and connect to the asset processor");
bool PlatformMainInfo::CopyCommandLine(int argc, char** argv)
{
for (int argIndex = 0; argIndex < argc; ++argIndex)
{
if (!AddArgument(argv[argIndex]))
{
return false;
}
}
return true;
}
bool PlatformMainInfo::AddArgument(const char* arg)
{
AZ_Error("Launcher", arg, "Attempting to add a nullptr command line argument!");
bool needsQuote = (strstr(arg, " ") != nullptr);
bool needsSpace = (m_commandLine[0] != 0);
// strip the previous null-term from the count to prevent double counting
m_commandLineLen = (m_commandLineLen == 0) ? 0 : (m_commandLineLen - 1);
// compute the expected length with the added argument
size_t argLen = strlen(arg);
size_t pendingLen = m_commandLineLen + argLen + 1 + (needsSpace ? 1 : 0) + (needsQuote ? 2 : 0); // +1 null-term, [+1 space], [+2 quotes]
if (pendingLen >= AZ_COMMAND_LINE_LEN)
{
AZ_Assert(false, "Command line exceeds the %d character limit!", AZ_COMMAND_LINE_LEN);
return false;
}
if (needsSpace)
{
m_commandLine[m_commandLineLen++] = ' ';
}
azsnprintf(m_commandLine + m_commandLineLen,
AZ_COMMAND_LINE_LEN - m_commandLineLen,
needsQuote ? "\"%s\"" : "%s",
arg);
// Inject the argument in the argument buffer to preserve/replicate argC and argV
azstrncpy(&m_commandLineArgBuffer[m_nextCommandLineArgInsertPoint],
AZ_COMMAND_LINE_LEN - m_nextCommandLineArgInsertPoint,
arg,
argLen+1);
m_argV[m_argC++] = &m_commandLineArgBuffer[m_nextCommandLineArgInsertPoint];
m_nextCommandLineArgInsertPoint += argLen + 1;
m_commandLineLen = pendingLen;
return true;
}
const char* GetReturnCodeString(ReturnCode code)
{
switch (code)
{
case ReturnCode::Success:
return "Success";
case ReturnCode::ErrBootstrapMismatch:
return "Mismatch detected between Launcher compiler defines and bootstrap values (LY_GAMEFOLDER/sys_game_folder).";
case ReturnCode::ErrCommandLine:
return "Failed to copy command line arguments";
case ReturnCode::ErrResourceLimit:
return "A resource limit failed to update";
case ReturnCode::ErrAppDescriptor:
return "Application descriptor file was not found";
case ReturnCode::ErrCrySystemLib:
return "Failed to load the CrySystem library";
case ReturnCode::ErrCrySystemInterface:
return "Failed to initialize the CrySystem Interface";
case ReturnCode::ErrCryEnvironment:
return "Failed to initialize the CryEngine global environment";
case ReturnCode::ErrAssetProccessor:
return "Failed to connect to AssetProcessor while the /Amazon/AzCore/Bootstrap/wait_for_connect value is 1\n."
"wait_for_connect can be set to 0 within the bootstrap to allow connecting to the AssetProcessor"
" to not be an error if unsuccessful.";
default:
return "Unknown error code";
}
}
void CopySettingsRegistryToCrySystemInitParams(const AZ::SettingsRegistryInterface& registry, SSystemInitParams& params)
{
constexpr AZStd::string_view DefaultRemoteIp = "127.0.0.1";
constexpr uint16_t DefaultRemotePort = 45643U;
AZ::SettingsRegistryInterface::FixedValueString settingsKeyPrefix = AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey;
AZ::SettingsRegistryInterface::FixedValueString settingsValueString;
AZ::s64 settingsValueInt{};
// remote filesystem
if (registry.Get(settingsValueInt, settingsKeyPrefix + "/remote_filesystem"))
{
params.remoteFileIO = settingsValueInt != 0;
}
// remote port
if(registry.Get(settingsValueInt, settingsKeyPrefix + "/remote_port"))
{
params.remotePort = aznumeric_cast<int>(settingsValueInt);
}
else
{
params.remotePort = DefaultRemotePort;
}
// remote ip
if (registry.Get(settingsValueString, settingsKeyPrefix + "/remote_ip"))
{
azstrncpy(AZStd::data(params.remoteIP), AZStd::size(params.remoteIP), settingsValueString.c_str(), settingsValueString.size());
}
else
{
azstrncpy(AZStd::data(params.remoteIP), AZStd::size(params.remoteIP), DefaultRemoteIp.data(), DefaultRemoteIp.size());
}
// connect_to_remote - also supports <platform>_connect_to_remote override
if (registry.Get(settingsValueInt, settingsKeyPrefix + "/" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_connect_to_remote")
|| registry.Get(settingsValueInt, settingsKeyPrefix + "/connect_to_remote"))
{
params.connectToRemote = settingsValueInt != 0;
}
#if !defined(DEDICATED_SERVER)
// wait_for_connect - also supports <platform>_wait_for_connect override
// Dedicated server does not depend on Asset Processor and assumes that assets are already prepared.
if (registry.Get(settingsValueInt, settingsKeyPrefix + "/" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_wait_for_connect")
|| registry.Get(settingsValueInt, settingsKeyPrefix + "/wait_for_connect"))
{
params.waitForConnection = settingsValueInt != 0;
}
#endif // defined(DEDICATED_SERVER)
// assets - also supports <platform>_assets override
settingsValueString.clear();
if (registry.Get(settingsValueString, settingsKeyPrefix + "/" AZ_TRAIT_OS_PLATFORM_CODENAME_LOWER "_assets")
|| registry.Get(settingsValueString, settingsKeyPrefix + "/assets"))
{
azstrncpy(AZStd::data(params.assetsPlatform), AZStd::size(params.assetsPlatform), settingsValueString.c_str(), settingsValueString.size());
}
// Project name - First tries sys_game_folder
settingsValueString.clear();
if (registry.Get(settingsValueString, settingsKeyPrefix + "/sys_game_folder"))
{
// sys_game_folder is the current way to do it
azstrncpy(AZStd::data(params.gameFolderName), AZStd::size(params.gameFolderName), settingsValueString.c_str(), settingsValueString.size());
}
// assetProcessor_branch_token
if (registry.Get(settingsValueInt, settingsKeyPrefix + "/assetProcessor_branch_token"))
{
azsnprintf(AZStd::data(params.branchToken), AZStd::size(params.branchToken), "0x%llx", settingsValueInt);
}
// Engine root path(also AppRoot path as well)
settingsValueString.clear();
if (registry.Get(settingsValueString, AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder))
{
azstrncpy(AZStd::data(params.rootPath), AZStd::size(params.rootPath), settingsValueString.c_str(), settingsValueString.size());
}
// Asset Cache Root path
settingsValueString.clear();
if (registry.Get(settingsValueString, AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
{
azstrncpy(AZStd::data(params.rootPathCache), AZStd::size(params.rootPathCache), settingsValueString.c_str(), settingsValueString.size());
}
// Asset Cache Game path (Includes as part of path, the current project name)
settingsValueString.clear();
if (registry.Get(settingsValueString, AZ::SettingsRegistryMergeUtils::FilePathKey_CacheGameFolder))
{
azstrncpy(AZStd::data(params.assetsPathCache), AZStd::size(params.assetsPathCache), settingsValueString.c_str(), settingsValueString.size());
azstrncpy(AZStd::data(params.assetsPath), AZStd::size(params.assetsPath), settingsValueString.c_str(), settingsValueString.size());
}
}
void CompileCriticalAssets();
void CreateRemoteFileIO();
bool ConnectToAssetProcessor()
{
bool connectedToAssetProcessor{};
// When the AssetProcessor is already launched it should take less than a second to perform a connection
// but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize
// and able to negotiate a connection when running a debug build
// and to negotiate a connection
// Setting the connectTimeout to 3 seconds if not set within the settings registry
AzFramework::AssetSystem::ConnectionSettings connectionSettings;
AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings);
connectionSettings.m_launchAssetProcessorOnFailedConnection = true;
connectionSettings.m_connectionIdentifier = AzFramework::AssetSystem::ConnectionIdentifiers::Game;
connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData)
{
AZ_TracePrintf("Launcher", "%.*s", aznumeric_cast<int>(logData.size()), logData.data());
};
AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings);
if (connectedToAssetProcessor)
{
AZ_TracePrintf("Launcher", "Connected to Asset Processor\n");
CreateRemoteFileIO();
CompileCriticalAssets();
}
return connectedToAssetProcessor;
}
//! Compiles the critical assets that are within the Engine directory of Lumberyard
//! This code should be in a centralized location, but doesn't belong in AzFramework
//! since it is specific to how Lumberyard projects has assets setup
void CompileCriticalAssets()
{
// VERY early on, as soon as we can, request that the asset system make sure the following assets take priority over others,
// so that by the time we ask for them there is a greater likelihood that they're already good to go.
// these can be loaded later but are still important:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "/texturemsg/");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/materials");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/geomcaches");
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::EscalateAssetBySearchTerm, "engineassets/objects");
// some are specifically extra important and will cause issues if missing completely:
AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::CompileAssetSync, "engineassets/objects/default.cgf");
}
//! Remote FileIO to use as a Virtual File System
//! Communication of FileIOBase operations occur through an AssetProcessor connection
void CreateRemoteFileIO()
{
AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get();
AZ::s64 allowRemoteFilesystem{};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, allowRemoteFilesystem,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "remote_filesystem");
if (allowRemoteFilesystem != 0)
{
// The SetInstance calls below will assert if this has already been set and we don't clear first
// Application::StartCommon will set a LocalFileIO base first.
// This provides an opportunity for the RemoteFileIO to override the direct instance
auto remoteFileIo = new AZ::IO::RemoteFileIO(AZ::IO::FileIOBase::GetDirectInstance()); // Wrap AZ:I::LocalFileIO the direct instance
AZ::IO::FileIOBase::SetDirectInstance(nullptr);
// Wrap AZ:IO::LocalFileIO the direct instance
AZ::IO::FileIOBase::SetDirectInstance(remoteFileIo);
}
}
//! Add the GameProjectName and Launcher build target name into the settings registry
void AddGameProjectNameToSettingsRegistry(AZ::SettingsRegistryInterface& settingsRegistry, AZ::CommandLine& commandLine)
{
auto gameProjectNameKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/sys_game_folder", AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey);
AZ::SettingsRegistryInterface::FixedValueString bootstrapGameProjectName;
settingsRegistry.Get(bootstrapGameProjectName, gameProjectNameKey);
const AZStd::string_view gameProjectName = GetGameProjectName();
AZ::SettingsRegistryInterface::FixedValueString gameProjectCommandLineOverride = R"(--regset=)";
gameProjectCommandLineOverride += gameProjectNameKey;
gameProjectCommandLineOverride += '=';
gameProjectCommandLineOverride += gameProjectName;
// Inject the Project Name into the CommandLine parameters, so that the Setting Registry
// always is set to the launcher's project name whenever the command line is merged into the Settings Registry
// This happens several times through application such as in GameApplication::Start
AZ::CommandLine::ParamContainer commandLineArgs;
commandLine.Dump(commandLineArgs);
commandLineArgs.emplace_back(gameProjectCommandLineOverride);
commandLine.Parse(commandLineArgs);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_CommandLine(settingsRegistry, commandLine, false);
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddRuntimeFilePaths(settingsRegistry);
const AZStd::string_view buildTargetName = LumberyardLauncher::GetBuildTargetName();
AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization(settingsRegistry, buildTargetName);
// Output a trace message if the sys_game_folder value read from the boostrap.cfg file doesn't match the value of the
// LY_GAMEFOLDER define built into the Launcher.
// This isn't any kind of error or ever warning, but is used as an informational message to the user
// that the launcher will use the always used the injected LY_GAMEFOLDER define
if (bootstrapGameProjectName != gameProjectName)
{
AZ_TracePrintf("Launcher", R"(The game project "%s" read into the Settings Registry from the bootstrap.cfg file)"
R"( does not match the LY_GAMEFOLDER define "%.*s")" "\n",
bootstrapGameProjectName.c_str(), aznumeric_cast<int>(gameProjectName.size()), gameProjectName.data());
}
AZ_TracePrintf("Launcher", R"(The game project name of "%.*s" is the value of the LY_GAMEFOLDER define.)" "\n"
R"(That value has been successfully set into the Settings Registry at key "%s/sys_game_folder" for Launcher target "%.*s")" "\n",
aznumeric_cast<int>(gameProjectName.size()), gameProjectName.data(),
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey,
aznumeric_cast<int>(buildTargetName.size()), buildTargetName.data());
}
ReturnCode Run(const PlatformMainInfo& mainInfo)
{
if (mainInfo.m_updateResourceLimits
&& !mainInfo.m_updateResourceLimits())
{
return ReturnCode::ErrResourceLimit;
}
// Game Application (AzGameFramework)
int gameArgC = mainInfo.m_argC;
char** gameArgV = const_cast<char**>(mainInfo.m_argV);
int* argCParam = (gameArgC > 0) ? &gameArgC : nullptr;
char*** argVParam = (gameArgC > 0) ? &gameArgV : nullptr;
AzGameFramework::GameApplication gameApplication(argCParam, argVParam);
// The settings registry has been created by the AZ::ComponentApplication constructor at this point
auto settingsRegistry = AZ::SettingsRegistry::Get();
if (settingsRegistry == nullptr)
{
// Settings registry must be available at this point in order to continue
return ReturnCode::ErrValidation;
}
// Inject the ${LY_GAMEFOLDER} project name define that from the Launcher build target
// into the settings registry
AddGameProjectNameToSettingsRegistry(*settingsRegistry, *gameApplication.GetAzCommandLine());
bool applyAppRootOverride = (AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE == 1);
AZ::SettingsRegistryInterface::FixedValueString pathToAssets;
if (!settingsRegistry->Get(pathToAssets, AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder))
{
// Default to mainInfo.m_appResource if the cache root folder is missing from the Settings Registry
pathToAssets = mainInfo.m_appResourcesPath;
AZ_Error("Launcher", false, "Unable to retrieve asset cache root folder from the settings registry at json pointer path %s",
AZ::SettingsRegistryMergeUtils::FilePathKey_CacheRootFolder);
}
else
{
AZ_TracePrintf("Launcher", "The asset cache folder of %s has been successfully read from the Settings Registry\n",
pathToAssets.c_str());
}
CryAllocatorsRAII cryAllocatorsRAII;
#if AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE
char appRootOverride[AZ_MAX_PATH_LEN] = { 0 };
{
// Search for the app root argument (--app-root <PATH>) where <PATH> is the app root path to set for the application
const static char* appRootArgPrefix = "--app-root";
size_t appRootArgPrefixLen = strlen(appRootArgPrefix);
const char* appRootArg = nullptr;
char cmdLineCopy[AZ_COMMAND_LINE_LEN] = { 0 };
azstrncpy(cmdLineCopy, AZ_COMMAND_LINE_LEN, mainInfo.m_commandLine, mainInfo.m_commandLineLen);
const char* delimiters = " ";
char* nextToken = nullptr;
char* token = azstrtok(cmdLineCopy, 0, delimiters, &nextToken);
while (token != NULL)
{
if (azstrnicmp(appRootArgPrefix, token, appRootArgPrefixLen) == 0)
{
appRootArg = azstrtok(nullptr, 0, delimiters, &nextToken);
break;
}
token = azstrtok(nullptr, 0, delimiters, &nextToken);
}
if (appRootArg)
{
AZStd::string_view appRootArgView = appRootArg;
size_t afterStartQuotes = appRootArgView.find_first_not_of(R"(")");
if (afterStartQuotes != AZStd::string_view::npos)
{
appRootArgView.remove_prefix(afterStartQuotes);
}
size_t beforeEndQuotes = appRootArgView.find_last_not_of(R"(")");
if (beforeEndQuotes != AZStd::string_view::npos)
{
appRootArgView.remove_suffix(appRootArgView.size() - (beforeEndQuotes + 1));
}
appRootArgView.copy(appRootOverride, AZ_MAX_PATH_LEN);
appRootOverride[appRootArgView.size()] = '\0';
pathToAssets = appRootOverride;
applyAppRootOverride = true;
}
}
#endif // AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE
// System Init Params ("Legacy" Lumberyard)
SSystemInitParams systemInitParams;
memset(&systemInitParams, 0, sizeof(SSystemInitParams));
{
AzGameFramework::GameApplication::StartupParameters gameApplicationStartupParams;
if (applyAppRootOverride)
{
// NOTE: setting this on android doesn't work when assets are packaged in the APK
gameApplicationStartupParams.m_appRootOverride = pathToAssets.c_str();
}
if (mainInfo.m_allocator)
{
gameApplicationStartupParams.m_allocator = mainInfo.m_allocator;
}
else if (AZ::AllocatorInstance<AZ::OSAllocator>::IsReady())
{
gameApplicationStartupParams.m_allocator = &AZ::AllocatorInstance<AZ::OSAllocator>::Get();
}
#if defined(AZ_MONOLITHIC_BUILD)
gameApplicationStartupParams.m_createStaticModulesCallback = CreateStaticModules;
gameApplicationStartupParams.m_loadDynamicModules = false;
#endif // defined(AZ_MONOLITHIC_BUILD)
CopySettingsRegistryToCrySystemInitParams(*settingsRegistry, systemInitParams);
gameApplication.Start({}, gameApplicationStartupParams);
#if defined(REMOTE_ASSET_PROCESSOR)
bool allowedEngineConnection = !systemInitParams.bToolMode && !systemInitParams.bTestMode && bg_ConnectToAssetProcessor;
//connect to the asset processor using the bootstrap values
bool connectedToAssetProcessor = false;
if (allowedEngineConnection)
{
if (!ConnectToAssetProcessor())
{
AZ::s64 waitForConnect{};
AZ::SettingsRegistryMergeUtils::PlatformGet(*settingsRegistry, waitForConnect,
AZ::SettingsRegistryMergeUtils::BootstrapSettingsRootKey, "wait_for_connect");
if (waitForConnect != 0)
{
AZ_Error("Launcher", false, "Failed to connect to AssetProcessor.");
return ReturnCode::ErrAssetProccessor;
}
}
}
#endif
AZ_Assert(AZ::AllocatorInstance<AZ::SystemAllocator>::IsReady(), "System allocator was not created or creation failed.");
//Initialize the Debug trace instance to create necessary environment variables
AZ::Debug::Trace::Instance().Init();
}
if (mainInfo.m_onPostAppStart)
{
mainInfo.m_onPostAppStart();
}
azstrncpy(systemInitParams.szSystemCmdLine, sizeof(systemInitParams.szSystemCmdLine),
mainInfo.m_commandLine, mainInfo.m_commandLineLen);
systemInitParams.pSharedEnvironment = AZ::Environment::GetInstance();
systemInitParams.sLogFileName = GetLogFilename();
systemInitParams.hInstance = mainInfo.m_instance;
systemInitParams.hWnd = mainInfo.m_window;
systemInitParams.pPrintSync = mainInfo.m_printSink;
if (strstr(mainInfo.m_commandLine, "-norandom"))
{
systemInitParams.bNoRandom = true;
}
systemInitParams.bDedicatedServer = IsDedicatedServer();
if (systemInitParams.remoteFileIO)
{
AZ_TracePrintf("Launcher", "Application is configured for VFS");
AZ_TracePrintf("Launcher", "Log and cache files will be written to the Cache directory on your host PC");
const char* message = "If your game does not run, check any of the following:\n"
"\t- Verify the remote_ip address is correct in bootstrap.cfg";
if (mainInfo.m_additionalVfsResolution)
{
AZ_TracePrintf("Launcher", "%s\n%s", message, mainInfo.m_additionalVfsResolution)
}
else
{
AZ_TracePrintf("Launcher", "%s", message)
}
}
else
{
AZ_TracePrintf("Launcher", "Application is configured to use device local files at %s\n", systemInitParams.rootPath);
AZ_TracePrintf("Launcher", "Log and cache files will be written to device storage\n");
const char* writeStorage = mainInfo.m_appWriteStoragePath;
if (writeStorage)
{
AZ_TracePrintf("Launcher", "User Storage will be set to %s/user\n", writeStorage);
azsnprintf(systemInitParams.userPath, AZ_MAX_PATH_LEN, "%s/user", writeStorage);
}
}
// Create CrySystem.
#if !defined(AZ_MONOLITHIC_BUILD)
AZStd::unique_ptr<DynamicModuleHandle> crySystemLibrary;
PFNCREATESYSTEMINTERFACE CreateSystemInterface = nullptr;
crySystemLibrary = DynamicModuleHandle::Create("CrySystem");
if (crySystemLibrary->Load(false))
{
CreateSystemInterface = crySystemLibrary->GetFunction<PFNCREATESYSTEMINTERFACE>("CreateSystemInterface");
if (CreateSystemInterface)
{
systemInitParams.pSystem = CreateSystemInterface(systemInitParams);
}
}
#else
systemInitParams.pSystem = CreateSystemInterface(systemInitParams);
#endif // !defined(AZ_MONOLITHIC_BUILD)
ReturnCode status = ReturnCode::Success;
if (systemInitParams.pSystem)
{
// Process queued events before main loop.
AZ::TickBus::ExecuteQueuedEvents();
#if !defined(SYS_ENV_AS_STRUCT)
gEnv = systemInitParams.pSystem->GetGlobalEnvironment();
#endif // !defined(SYS_ENV_AS_STRUCT)
if (gEnv && gEnv->pConsole)
{
// Execute autoexec.cfg to load the initial level
gEnv->pConsole->ExecuteString("exec autoexec.cfg");
gEnv->pSystem->ExecuteCommandLine(false);
// Run the main loop
RunMainLoop(gameApplication);
}
else
{
status = ReturnCode::ErrCryEnvironment;
}
}
else
{
status = ReturnCode::ErrCrySystemInterface;
}
#if !defined(AZ_MONOLITHIC_BUILD)
crySystemLibrary.reset(nullptr);
#endif // !defined(AZ_MONOLITHIC_BUILD)
gameApplication.Stop();
AZ::Debug::Trace::Instance().Destroy();
return status;
}
}
+128
View File
@@ -0,0 +1,128 @@
/*
* 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 <AzCore/PlatformDef.h> // for AZ_COMMAND_LINE_LEN
#include <AzCore/Debug/Trace.h>
#include <AzCore/IO/SystemFile.h>
#include <CryCommon/platform.h>
struct IOutputPrintSink;
namespace LumberyardLauncher
{
struct CryAllocatorsRAII
{
CryAllocatorsRAII()
{
AZ_Assert(!AZ::AllocatorInstance<AZ::LegacyAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ_Assert(!AZ::AllocatorInstance<CryStringAllocator>::IsReady(), "Expected allocator to not be initialized, hunt down the static that is initializing it");
AZ::AllocatorInstance<AZ::LegacyAllocator>::Create();
AZ::AllocatorInstance<CryStringAllocator>::Create();
}
~CryAllocatorsRAII()
{
AZ::AllocatorInstance<CryStringAllocator>::Destroy();
AZ::AllocatorInstance<AZ::LegacyAllocator>::Destroy();
}
};
#define COMMAND_LINE_ARG_COUNT_LIMIT (AZ_COMMAND_LINE_LEN+1) / 2 // Assume that the limit to how many arguments we can maintain is the max buffer size divided by 2
// to account for an argument and a spec in between each argument (with the worse case scenario being
struct PlatformMainInfo
{
typedef bool (*ResourceLimitUpdater)();
typedef void (*OnPostApplicationStart)();
PlatformMainInfo() = default;
//! Copy the command line into a buffer as is or reconstruct a
//! quoted version of the command line from the arg c/v. The
//! internal buffer is fixed to \ref AZ_COMMAND_LINE_LEN meaning
//! this call can fail if the command line exceeds that length
bool CopyCommandLine(int argc, char** argv);
bool AddArgument(const char* arg);
char m_commandLine[AZ_COMMAND_LINE_LEN] = { 0 };
size_t m_commandLineLen = 0;
//! Keep static sized arrays to manage and provide the main arguments (argc, argv)
char m_commandLineArgBuffer[AZ_COMMAND_LINE_LEN] = { 0 };
size_t m_nextCommandLineArgInsertPoint = 0;
int m_argC = 0;
char* m_argV[COMMAND_LINE_ARG_COUNT_LIMIT] = { nullptr };
ResourceLimitUpdater m_updateResourceLimits = nullptr; //!< callback for updating system resources, if necessary
OnPostApplicationStart m_onPostAppStart = nullptr; //!< callback notifying the platform specific entry point that AzGameFramework::GameApplication::Start has been called
AZ::IAllocatorAllocate* m_allocator = nullptr; //!< Used to allocate the temporary bootstrap memory, as well as the main \ref SystemAllocator heap. If null, OSAllocator will be used
const char* m_appResourcesPath = "."; //!< Path to the device specific assets, default is equivalent to blank path in ParseEngineConfig
const char* m_appWriteStoragePath = nullptr; //!< Path to writeable storage if different than assets path, used to override userPath and logPath
const char* m_additionalVfsResolution = nullptr; //!< additional things to check if VFS is not working for the desired platform
void* m_window = nullptr; //!< maps to \ref SSystemInitParams::hWnd
void* m_instance = nullptr; //!< maps to \ref SSystemInitParams::hInstance
IOutputPrintSink* m_printSink = nullptr; //!< maps to \ref SSystemInitParams::pPrintSync
};
enum class ReturnCode : unsigned char
{
Success = 0,
ErrExePath, //!< Failed to get the executable path
ErrBootstrapMismatch, //!< Failed to validate launcher compiler defines with bootstrap values
ErrCommandLine, //!< Failed to copy the command line
ErrValidation, //!< Failed to validate secret
ErrResourceLimit, //!< Failed to increase unix resource limits
ErrAppDescriptor, //!< Failed to locate the application descriptor file
ErrCrySystemLib, //!< Failed to load required CrySystem library
ErrCrySystemInterface, //!< Failed to create the CrySystem interface
ErrCryEnvironment, //!< Failed to initialize the CryEngine environment
ErrAssetProccessor, //!< Failed to connect to the asset processor
ErrUnitTestFailure, //!< In Unit Test mode, one or more of the unit tests failed.
ErrUnitTestNotSupported,//!< In Unit Test mode is not supported in its current configuration
};
const char* GetReturnCodeString(ReturnCode code);
//! The main entry point for all lumberyard launchers
ReturnCode Run(const PlatformMainInfo& mainInfo = PlatformMainInfo());
//////////////////////////////////////////////////////////////////////////
// The following functions are defined by launcher project
//////////////////////////////////////////////////////////////////////////
//! This function returns the name of the project
const AZStd::string_view GetGameProjectName();
//! This function returns the build system target name
const AZStd::string_view GetBuildTargetName();
//////////////////////////////////////////////////////////////////////////
// The following functions are defined per launcher type (e.g. Game/Server)
//////////////////////////////////////////////////////////////////////////
//! Indicates if it should wait for a connection to the AssetProcessor (will attempt to open it if true)
bool WaitForAssetProcessorConnect();
//! Indicates if it is a dedicated server
bool IsDedicatedServer();
//! Gets the name of the log file to use
const char* GetLogFilename();
}
+39
View File
@@ -0,0 +1,39 @@
/*
* 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 <AzCore/std/string/string_view.h>
#if defined(AZ_MONOLITHIC_BUILD)
#include <StaticModules.inl>
#endif // defined(AZ_MONOLITHIC_BUILD)
namespace LumberyardLauncher
{
//! This file is to be added only to the ${project}.[Game|Server]Launcher build target
//! This function returns the build system target name
const AZStd::string_view GetBuildTargetName()
{
#if !defined (LY_CMAKE_TARGET)
#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target"
#endif
return { LY_CMAKE_TARGET };
}
const AZStd::string_view GetGameProjectName()
{
#if !defined (LY_GAME_PROJECT_NAME)
#error "LY_GAME_PROJECT_NAME must be defined in order to for the Launcher to run using a Game Project"
#endif
return { LY_GAME_PROJECT_NAME };
}
}
@@ -0,0 +1,13 @@
#
# 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.
#
# Android launcher are shared objects that are loaded by Android's own launcher
set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE MODULE)
@@ -0,0 +1,435 @@
/*
* 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 <Launcher.h>
#include <../Common/UnixLike/Launcher_UnixLike.h>
#include <AzCore/Android/AndroidEnv.h>
#include <AzCore/Android/Utils.h>
#include <AzCore/Android/JNI/JNI.h>
#include <AzCore/Android/JNI/Object.h>
#include <AzCore/Android/JNI/scoped_ref.h>
#include <AzFramework/API/ApplicationAPI_Platform.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
#include <AzGameFramework/Application/GameApplication.h>
#include <IConsole.h>
#include <android/asset_manager_jni.h>
#include <android/log.h>
#include <android/native_activity.h>
#include <android/native_window.h>
#include <android_native_app_glue.h>
#include <sys/resource.h>
#include <sys/types.h>
#if defined(AZ_ENABLE_TRACING) || defined(RELEASE_LOGGING)
#define ENABLE_LOGGING
#endif // defined(AZ_ENABLE_TRACING) || defined(RELEASE_LOGGING)
#if defined(ENABLE_LOGGING)
#define LOG_TAG "LMBR"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__))
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__))
struct COutputPrintSink
: public IOutputPrintSink
{
virtual void Print(const char* message)
{
LOGI("%s", message);
}
};
COutputPrintSink g_androidPrintSink;
#else
#define LOGI(...)
#define LOGE(...)
#endif // !defined(_RELEASE)
#define MAIN_EXIT_FAILURE(_appState, ...) \
LOGE("****************************************************************"); \
LOGE("STARTUP FAILURE - EXITING"); \
LOGE("REASON:"); \
LOGE(__VA_ARGS__); \
LOGE("****************************************************************"); \
_appState->userData = nullptr; \
ANativeActivity_finish(_appState->activity); \
while (_appState->destroyRequested == 0) { \
g_eventDispatcher.PumpAllEvents(); \
} \
return;
namespace
{
class NativeEventDispatcher
: public AzFramework::AndroidEventDispatcher
{
public:
NativeEventDispatcher()
: m_appState(nullptr)
{
}
~NativeEventDispatcher() = default;
void PumpAllEvents() override
{
bool continueRunning = true;
while (continueRunning)
{
continueRunning = PumpEvents(&ALooper_pollAll);
}
}
void PumpEventLoopOnce() override
{
PumpEvents(&ALooper_pollOnce);
}
void SetAppState(android_app* appState)
{
m_appState = appState;
}
private:
// signature of ALooper_pollOnce and ALooper_pollAll -> int timeoutMillis, int* outFd, int* outEvents, void** outData
typedef int (*EventPumpFunc)(int, int*, int*, void**);
bool PumpEvents(EventPumpFunc looperFunc)
{
if (!m_appState)
{
return false;
}
int events = 0;
android_poll_source* source = nullptr;
const AZ::Android::AndroidEnv* androidEnv = AZ::Android::AndroidEnv::Get();
// when timeout is negative, the function will block until an event is received
const int result = looperFunc(androidEnv->IsRunning() ? 0 : -1, nullptr, &events, reinterpret_cast<void**>(&source));
// the value returned from the looper poll func is either:
// 1. the identifier associated with the event source (>= 0) and has event data that needs to be processed manually
// 2. an ALOOPER_POLL_* enum (< 0) indicating there is no data to be processed due to error or callback(s) registered
// with the event source were called
const bool validIdentifier = (result >= 0);
if (validIdentifier && source)
{
source->process(m_appState, source);
}
const bool destroyRequested = (m_appState->destroyRequested != 0);
if (destroyRequested)
{
AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::ExitMainLoop);
}
return (validIdentifier && !destroyRequested);
}
android_app* m_appState;
};
NativeEventDispatcher g_eventDispatcher;
bool g_windowInitialized = false;
void OnPostAppStart()
{
// set the event dispatcher with the application framework
AzFramework::AndroidAppRequests::Bus::Broadcast(&AzFramework::AndroidAppRequests::SetEventDispatcher, &g_eventDispatcher);
// queue the dismissal of the system splash screen in case the engine splash is disabled
AZ::TickBus::QueueFunction([](){
AZ::Android::Utils::DismissSplashScreen();
});
}
int32_t HandleInputEvents(android_app* app, AInputEvent* event)
{
AzFramework::RawInputNotificationBusAndroid::Broadcast(&AzFramework::RawInputNotificationsAndroid::OnRawInputEvent, event);
return 0;
}
void HandleApplicationLifecycleEvents(android_app* appState, int32_t command)
{
#if defined(ENABLE_LOGGING)
const char* commandNames[] = {
"APP_CMD_INPUT_CHANGED",
"APP_CMD_INIT_WINDOW",
"APP_CMD_TERM_WINDOW",
"APP_CMD_WINDOW_RESIZED",
"APP_CMD_WINDOW_REDRAW_NEEDED",
"APP_CMD_CONTENT_RECT_CHANGED",
"APP_CMD_GAINED_FOCUS",
"APP_CMD_LOST_FOCUS",
"APP_CMD_CONFIG_CHANGED",
"APP_CMD_LOW_MEMORY",
"APP_CMD_START",
"APP_CMD_RESUME",
"APP_CMD_SAVE_STATE",
"APP_CMD_PAUSE",
"APP_CMD_STOP",
"APP_CMD_DESTROY",
};
if (command >= 0 && command < sizeof(commandNames))
{
LOGI("Engine command received: %s", commandNames[command]);
}
else
{
LOGW("Unknown engine command received: %d", command);
}
#endif
AZ::Android::AndroidEnv* androidEnv = static_cast<AZ::Android::AndroidEnv*>(appState->userData);
if (!androidEnv)
{
return;
}
switch (command)
{
case APP_CMD_GAINED_FOCUS:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnGainedFocus);
}
break;
case APP_CMD_LOST_FOCUS:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnLostFocus);
}
break;
case APP_CMD_PAUSE:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnPause);
androidEnv->SetIsRunning(false);
}
break;
case APP_CMD_RESUME:
{
androidEnv->SetIsRunning(true);
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnResume);
}
break;
case APP_CMD_DESTROY:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnDestroy);
}
break;
case APP_CMD_INIT_WINDOW:
{
g_windowInitialized = true;
androidEnv->SetWindow(appState->window);
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowInit);
}
break;
case APP_CMD_TERM_WINDOW:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowDestroy);
androidEnv->SetWindow(nullptr);
}
break;
case APP_CMD_LOW_MEMORY:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnLowMemory);
}
break;
case APP_CMD_CONFIG_CHANGED:
{
androidEnv->UpdateConfiguration();
}
break;
case APP_CMD_WINDOW_REDRAW_NEEDED:
{
AzFramework::AndroidLifecycleEvents::Bus::Broadcast(
&AzFramework::AndroidLifecycleEvents::Bus::Events::OnWindowRedrawNeeded);
}
break;
}
}
void OnWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* rect)
{
android_app* app = static_cast<android_app*>(activity->instance);
int8_t cmd = APP_CMD_WINDOW_REDRAW_NEEDED;
if (write(app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd))
{
LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
}
}
}
// This is the main entry point of a native application that is using android_native_app_glue.
// It runs in its own thread, with its own event loop for receiving input events
void android_main(android_app* appState)
{
// Adding a start up banner so you can see when the game is starting up in amongst the logcat spam
LOGI("****************************************************************");
LOGI("* Amazon Lumberyard - Launching Game... *");
LOGI("****************************************************************");
// setup the system command handler which are guaranteed to be called on the same
// thread the events are pumped
appState->onAppCmd = HandleApplicationLifecycleEvents;
appState->onInputEvent = HandleInputEvents;
g_eventDispatcher.SetAppState(appState);
// This callback will notify us when the orientation of the device changes.
// While Android does have an onNativeWindowResized callback, it is never called in android_native_app_glue when the window size changes.
// The onNativeConfigChanged callback is called too early(before the window size has changed), so we won't have the correct window size at that point.
appState->activity->callbacks->onNativeWindowRedrawNeeded = OnWindowRedrawNeeded;
// setup the android environment
AZ::AllocatorInstance<AZ::OSAllocator>::Create();
{
AZ::Android::AndroidEnv::Descriptor descriptor;
descriptor.m_jvm = appState->activity->vm;
descriptor.m_activityRef = appState->activity->clazz;
descriptor.m_assetManager = appState->activity->assetManager;
descriptor.m_configuration = appState->config;
descriptor.m_appPrivateStoragePath = appState->activity->internalDataPath;
descriptor.m_appPublicStoragePath = appState->activity->externalDataPath;
descriptor.m_obbStoragePath = appState->activity->obbPath;
if (!AZ::Android::AndroidEnv::Create(descriptor))
{
AZ::Android::AndroidEnv::Destroy();
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
MAIN_EXIT_FAILURE(appState, "Failed to create the AndroidEnv");
}
AZ::Android::AndroidEnv* androidEnv = AZ::Android::AndroidEnv::Get();
appState->userData = androidEnv;
androidEnv->SetIsRunning(true);
}
// sync the window creation
while (!g_windowInitialized)
{
g_eventDispatcher.PumpAllEvents();
}
// Now that the window has been created we can show the java splash screen. We need
// to do it here and not in the window init event because every time the app is
// backgrounded/foregrounded the window is destroyed/created, respectively. So, we
// don't want to show the splash screen when we resumed from a paused state.
AZ::Android::Utils::ShowSplashScreen();
// run the Lumberyard application
using namespace LumberyardLauncher;
PlatformMainInfo mainInfo;
mainInfo.m_updateResourceLimits = IncreaseResourceLimits;
mainInfo.m_onPostAppStart = OnPostAppStart;
mainInfo.m_appResourcesPath = AZ::Android::Utils::FindAssetsDirectory();
mainInfo.m_additionalVfsResolution = "\t- Make sure \'adb reverse\' is setup for the device when connecting to localhost";
// Always add the app as the first arg to mimic the way other platforms start with the executable name.
const char* packageName = AZ::Android::Utils::GetPackageName();
if (packageName)
{
mainInfo.AddArgument(packageName);
}
// Get the string extras and pass them along as cmd line params
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> activityObject(AZ::Android::JNI::GetEnv()->GetObjectClass(appState->activity->clazz), appState->activity->clazz);
activityObject.RegisterMethod("getIntent", "()Landroid/content/Intent;");
jobject intent = activityObject.InvokeObjectMethod<jobject>("getIntent");
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> intentObject(AZ::Android::JNI::GetEnv()->GetObjectClass(intent), intent);
intentObject.RegisterMethod("getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
intentObject.RegisterMethod("getExtras", "()Landroid/os/Bundle;");
jobject extras = intentObject.InvokeObjectMethod<jobject>("getExtras");
if (extras)
{
// Get the set of keys
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> extrasObject(AZ::Android::JNI::GetEnv()->GetObjectClass(extras), extras);
extrasObject.RegisterMethod("keySet", "()Ljava/util/Set;");
jobject extrasKeySet = extrasObject.InvokeObjectMethod<jobject>("keySet");
// get the array of string objects
AZ::Android::JNI::Internal::Object<AZ::OSAllocator> extrasKeySetObject(AZ::Android::JNI::GetEnv()->GetObjectClass(extrasKeySet), extrasKeySet);
extrasKeySetObject.RegisterMethod("toArray", "()[Ljava/lang/Object;");
jobjectArray extrasKeySetArray = extrasKeySetObject.InvokeObjectMethod<jobjectArray>("toArray");
int extrasKeySetArraySize = AZ::Android::JNI::GetEnv()->GetArrayLength(extrasKeySetArray);
for (int x = 0; x < extrasKeySetArraySize; x++)
{
jstring keyObject = static_cast<jstring>(AZ::Android::JNI::GetEnv()->GetObjectArrayElement(extrasKeySetArray, x));
AZ::OSString value = intentObject.InvokeStringMethod("getStringExtra", keyObject);
const char* keyChars = AZ::Android::JNI::GetEnv()->GetStringUTFChars(keyObject, 0);
char argName[AZ_COMMAND_LINE_LEN] = { 0 };
azsprintf(argName, "-%s", keyChars);
mainInfo.AddArgument(argName);
mainInfo.AddArgument(value.c_str());
AZ::Android::JNI::GetEnv()->ReleaseStringUTFChars(keyObject, keyChars);
}
}
#if defined(_RELEASE)
mainInfo.m_appWriteStoragePath = AZ::Android::Utils::GetAppPrivateStoragePath();
#else
mainInfo.m_appWriteStoragePath = AZ::Android::Utils::GetAppPublicStoragePath();
#endif // defined(_RELEASE)
#if defined(ENABLE_LOGGING)
mainInfo.m_printSink = &g_androidPrintSink;
#endif // defined(ENABLE_LOGGING)
ReturnCode status = Run(mainInfo);
AZ::Android::AndroidEnv::Destroy();
AZ::AllocatorInstance<AZ::OSAllocator>::Destroy();
if (status != ReturnCode::Success)
{
MAIN_EXIT_FAILURE(appState, GetReturnCodeString(status));
}
}
@@ -0,0 +1,18 @@
/*
* 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
#define AZ_TRAIT_LAUNCHER_LOWER_CASE_PATHS 1
#define AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE 0
#define AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE 0
#define AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE 1
#define AZ_TRAIT_SHARED_LIBRARY_FILENAME_FORMAT "%s/lib%s.so"
@@ -0,0 +1,14 @@
/*
* 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 <Launcher_Traits_Android.h>
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,18 @@
#
# 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.
#
if(LY_MONOLITHIC_GAME) # only Atom is supported in monolithic
list(APPEND LY_BUILD_DEPENDENCIES Legacy::CryRenderOther)
else()
set(LY_RUNTIME_DEPENDENCIES
Legacy::CryRenderGL
)
endif()
@@ -0,0 +1,15 @@
/*
* 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 the required native app glue source from the configured NDK path directly
#include <android_native_app_glue.c>
@@ -0,0 +1,16 @@
#
# 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.
#
set(LY_INCLUDE_DIRECTORIES
PRIVATE
${LY_NDK_NATIVE_APP_GLUE_SRC_DIR}
)
@@ -0,0 +1,19 @@
#
# 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.
#
set(FILES
Launcher_Android.cpp
Launcher_Traits_Android.h
Launcher_Traits_Platform.h
../Common/UnixLike/Launcher_UnixLike.cpp
../Common/UnixLike/Launcher_UnixLike.h
native_app_glue_include.c
)
@@ -0,0 +1,18 @@
/*
* 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
namespace LumberyardLauncher
{
const char* GetAppResourcePath();
}
@@ -0,0 +1,34 @@
/*
* 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 "Launcher_Apple.h"
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
#include <Foundation/Foundation.h>
namespace LumberyardLauncher
{
const char* GetAppResourcePath()
{
static char pathToAssets[AZ_MAX_PATH_LEN] = { 0 };
if (pathToAssets[0] == 0)
{
const char* pathToResources = [[[NSBundle mainBundle] resourcePath] UTF8String];
azsnprintf(pathToAssets, AZ_MAX_PATH_LEN, "%s/%s", pathToResources, "assets");
}
return pathToAssets;
}
}
@@ -0,0 +1,104 @@
/*
* 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 "Launcher_UnixLike.h"
#include <AzCore/base.h>
#include <AzCore/Debug/Trace.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <cerrno>
#include <cstring>
#include <limits.h>
#include <stdlib.h>
namespace
{
// return true if the limit was updated and setlimit needs to be called, false otherwise
typedef bool(*ResourceLimitUpdater)(rlimit&);
bool IncreaseMaxToInfinity(rlimit& limit)
{
if (limit.rlim_max != RLIM_INFINITY)
{
limit.rlim_max = RLIM_INFINITY;
return true;
}
return false;
}
bool IncreaseCurrentToMax(rlimit& limit)
{
if (limit.rlim_cur < limit.rlim_max)
{
limit.rlim_cur = limit.rlim_max;
return true;
}
return false;
}
bool IncreaseResourceLimit(int resource, ResourceLimitUpdater updateLimit)
{
rlimit limit;
if (getrlimit(resource, &limit) != 0)
{
AZ_Error("Launcher", false, "[ERROR] Failed to get limit for resource %d. Error: %s", resource, strerror(errno));
return false;
}
if (updateLimit(limit))
{
if (setrlimit(resource, &limit) != 0)
{
AZ_Error("Launcher", false, "[ERROR] Failed to update resource limit for resource %d. Error: %s", resource, strerror(errno));
return false;
}
}
return true;
}
}
namespace LumberyardLauncher
{
bool IncreaseResourceLimits()
{
return (IncreaseResourceLimit(RLIMIT_CORE, IncreaseMaxToInfinity)
&& IncreaseResourceLimit(RLIMIT_STACK, IncreaseCurrentToMax));
}
const char* GetAbsolutePath(char* absolutePathBuffer, size_t absolutePathBufferSize, const char* inputPath)
{
// Normalize the path
AZ_Assert(absolutePathBufferSize>0,"Input buffer size for absolutePathBuffer must be greater than zero.");
char normalizedFullPathBuffer[PATH_MAX];
const char* normalizedFullPath = NULL;
if (strlen(inputPath)>0)
{
normalizedFullPath = realpath(inputPath, normalizedFullPathBuffer);
}
if (normalizedFullPath == NULL)
{
// Unable to resolve the absolute path, set the buffer to blank
absolutePathBuffer[0] = '\0';
}
else
{
// The path was resolved to an absolute path, copy to the input buffer the result
azstrncpy(absolutePathBuffer, absolutePathBufferSize, normalizedFullPath,strlen(normalizedFullPath)+1);
}
return absolutePathBuffer;
}
}
@@ -0,0 +1,26 @@
/*
* 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 <cstddef>
namespace LumberyardLauncher
{
// Increase the core and stack limits
bool IncreaseResourceLimits();
// Get the absolute path for any given input path if possible. If an absolute path cannot be
// resolved, then return an empty string.
const char* GetAbsolutePath(char* absolutePathBuffer, size_t absolutePathBufferSize, const char* inputPath);
}
@@ -0,0 +1,13 @@
#
# 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.
#
set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE APPLICATION)
@@ -0,0 +1,115 @@
/*
* 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 <Launcher.h>
#include <../Common/UnixLike/Launcher_UnixLike.h>
#include <AzCore/Debug/StackTracer.h>
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
#include <CryLibrary.h>
#include <execinfo.h>
#include <libgen.h>
#include <netdb.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/types.h>
namespace
{
void SignalHandler(int sig, siginfo_t* info, void* secret)
{
FILE* ftrace = fopen("backtrace.log", "w");
if (!ftrace)
{
ftrace = stderr;
}
AZ::Debug::StackFrame frames[25];
unsigned int frameCount = AZ_ARRAY_SIZE(frames);
frameCount = AZ::Debug::StackRecorder::Record(frames, frameCount);
AZ::Debug::SymbolStorage::StackLine lines[25];
AZ::Debug::SymbolStorage::DecodeFrames(frames, frameCount, lines);
for (unsigned int frame = 0; frame < frameCount; ++frame)
{
fprintf(ftrace, "%s", lines[frame]);
}
if (ftrace != stderr)
{
fclose(ftrace);
}
abort();
}
void InitStackTracer()
{
struct sigaction sa;
sa.sa_sigaction = SignalHandler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &sa, 0);
sigaction(SIGBUS, &sa, 0);
sigaction(SIGILL, &sa, 0);
prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
}
}
int main(int argc, char** argv)
{
bool waitForDebugger = false;
for (int i = 1; i < argc; ++i)
{
if (!strcmp(argv[i], "-wait"))
{
waitForDebugger = true;
break;
}
}
if (waitForDebugger)
{
while(!AZ::Debug::Trace::IsDebuggerPresent())
{
AZStd::this_thread::sleep_for(AZStd::chrono::milliseconds(50));
}
}
InitStackTracer();
using namespace LumberyardLauncher;
#if !defined(AZ_MONOLITHIC_BUILD)
char exePath[AZ_MAX_PATH_LEN] = { 0 };
if (readlink("/proc/self/exe", exePath, AZ_MAX_PATH_LEN) == -1)
{
return static_cast<int>(ReturnCode::ErrExePath);
}
char* runDir = dirname(exePath);
SetModulePath(runDir);
#endif // !defined(AZ_MONOLITHIC_BUILD)
PlatformMainInfo mainInfo;
mainInfo.m_updateResourceLimits = IncreaseResourceLimits;
bool ret = mainInfo.CopyCommandLine(argc, argv);
// run the Lumberyard application
ReturnCode status = ret ?
Run(mainInfo) :
ReturnCode::ErrCommandLine;
return static_cast<int>(status);
}
@@ -0,0 +1,18 @@
/*
* 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
#define AZ_TRAIT_LAUNCHER_LOWER_CASE_PATHS 0
#define AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE 0
#define AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE 1
#define AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE 1
#define AZ_TRAIT_SHARED_LIBRARY_FILENAME_FORMAT "%s/lib%s.so"
@@ -0,0 +1,14 @@
/*
* 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 <Launcher_Traits_Linux.h>
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,22 @@
#
# 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.
#
if (LY_MONOLITHIC_GAME) # only Atom is supported in monolithic
set(LY_BUILD_DEPENDENCIES
PUBLIC
Legacy::CryRenderOther
)
else()
set(LY_BUILD_DEPENDENCIES
PRIVATE
Legacy::CryRenderGL
)
endif()
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,18 @@
#
# 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.
#
set(FILES
Launcher_Linux.cpp
Launcher_Traits_Linux.h
Launcher_Traits_Platform.h
../Common/UnixLike/Launcher_UnixLike.cpp
../Common/UnixLike/Launcher_UnixLike.h
)
@@ -0,0 +1,13 @@
#
# 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.
#
set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE APPLICATION)
@@ -0,0 +1,65 @@
/*
* 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 <Launcher.h>
#include <LumberyardApplication_Mac.h>
#include <../Common/Apple/Launcher_Apple.h>
#include <../Common/UnixLike/Launcher_UnixLike.h>
#if AZ_TESTS_ENABLED
int main(int argc, char* argv[])
{
// TODO: Implement for Mac
return static_cast<int>(LumberyardLauncher::ReturnCode::ErrUnitTestNotSupported);
}
#else
int main(int argc, char* argv[])
{
// Ensure the process is a foreground application. Must be done before creating the application.
ProcessSerialNumber processSerialNumber = { 0, kCurrentProcess };
TransformProcessType(&processSerialNumber, kProcessTransformToForegroundApplication);
// Create a memory pool, a custom AppKit application, and a custom AppKit application delegate.
NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init];
[LumberyardApplication_Mac sharedApplication];
[NSApp setDelegate: [[LumberyardApplicationDelegate_Mac alloc] init]];
// Register some default application behaviours
[[NSUserDefaults standardUserDefaults] registerDefaults:
[[NSDictionary alloc] initWithObjectsAndKeys:
[NSNumber numberWithBool: FALSE], @"AppleMomentumScrollSupported",
[NSNumber numberWithBool: FALSE], @"ApplePressAndHoldEnabled",
nil]];
// Launch the AppKit application and release the memory pool.
[NSApp finishLaunching];
[autoreleasePool release];
// run the Lumberyard application
using namespace LumberyardLauncher;
PlatformMainInfo mainInfo;
mainInfo.m_updateResourceLimits = IncreaseResourceLimits;
mainInfo.m_appResourcesPath = GetAppResourcePath();
bool ret = mainInfo.CopyCommandLine(argc, argv);
ReturnCode status = ret ?
Run(mainInfo) :
ReturnCode::ErrCommandLine;
return static_cast<int>(status);
}
#endif // AZ_TESTS_ENABLED
@@ -0,0 +1,18 @@
/*
* 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
#define AZ_TRAIT_LAUNCHER_LOWER_CASE_PATHS 1
#define AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE 1
#define AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE 1
#define AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE 1
#define AZ_TRAIT_SHARED_LIBRARY_FILENAME_FORMAT "%s/lib%s.dylib"
@@ -0,0 +1,14 @@
/*
* 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 <Launcher_Traits_Mac.h>
@@ -0,0 +1,19 @@
/*
* 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 <Launcher.h>
#include <LumberyardApplication_Mac.h>
@implementation LumberyardApplicationDelegate_Mac
@end // LumberyardApplicationDelegate_Mac Implementation
@@ -0,0 +1,25 @@
/*
* 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 <AppKit/NSApplication.h>
@interface LumberyardApplication_Mac : NSApplication
{
}
@end // LumberyardApplication_Mac Interface
@interface LumberyardApplicationDelegate_Mac : NSObject<NSApplicationDelegate>
{
}
@end // LumberyardApplicationDelegate_Mac Interface
@@ -0,0 +1,19 @@
/*
* 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 <Launcher.h>
#include <LumberyardApplication_Mac.h>
@implementation LumberyardApplication_Mac
@end // LumberyardApplication_Mac Implementation
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,59 @@
#
# 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.
#
set(LY_TARGET_PROPERTIES
BUILD_RPATH @executable_path/
)
if(LY_MONOLITHIC_GAME) # only Atom is supported in monolithic builds
list(APPEND LY_BUILD_DEPENDENCIES Legacy::CryRenderOther)
else()
set(LY_RUNTIME_DEPENDENCIES Legacy::CryRenderMetal)
endif()
# Add resources and app icons to launchers
get_target_property(${project}_GEM_DIR ${project} SOURCE_DIR)
get_filename_component(${project}_GEM_DIR ${${project}_GEM_DIR} DIRECTORY)
set(ly_game_resource_folder ${${project}_GEM_DIR}/Resources/Platform/Mac)
if (NOT EXISTS ${ly_game_resource_folder})
set(ly_game_resource_folder ${${project}_GEM_DIR}/Resources/MacLauncher)
if (NOT EXISTS ${ly_game_resource_folder})
message(FATAL_ERROR "Missing expected resources folder")
endif()
endif()
target_sources(${project}.GameLauncher PRIVATE ${ly_game_resource_folder}/Images.xcassets)
set_target_properties(${project}.GameLauncher PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${ly_game_resource_folder}/Info.plist
RESOURCE ${ly_game_resource_folder}/Images.xcassets
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME ${project}AppIcon
)
set(layout_tool_dir ${LY_ROOT_FOLDER}/cmake/Tools)
add_custom_command(TARGET ${project}.GameLauncher POST_BUILD
COMMAND ${LY_PYTHON_CMD} layout_tool.py
--dev-root "${LY_ROOT_FOLDER}"
-p Mac
-a ${LY_ASSET_DEPLOY_ASSET_TYPE}
-g ${project}
-m ${LY_ASSET_DEPLOY_MODE}
--create-layout-root
-l $<TARGET_BUNDLE_DIR:${project}.GameLauncher>/Contents/Resources/assets
--build-config $<CONFIG>
--warn-on-missing-assets
--verify
${LY_OVERRIDE_PAK_ARGUMENT}
WORKING_DIRECTORY ${layout_tool_dir}
COMMENT "Synchronizing Layout Assets ..."
VERBATIM
)
@@ -0,0 +1,22 @@
#
# 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.
#
set(LY_COMPILE_OPTIONS
PRIVATE
-xobjective-c++
)
set(LY_BUILD_DEPENDENCIES
PUBLIC
3rdParty::LibTomCrypt
3rdParty::LibTomMath
)
@@ -0,0 +1,23 @@
#
# 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.
#
set(FILES
Launcher_Mac.mm
Launcher_Traits_Mac.h
Launcher_Traits_Platform.h
LumberyardApplication_Mac.h
LumberyardApplication_Mac.mm
LumberyardApplicationDelegate_Mac.mm
../Common/Apple/Launcher_Apple.mm
../Common/Apple/Launcher_Apple.h
../Common/UnixLike/Launcher_UnixLike.cpp
../Common/UnixLike/Launcher_UnixLike.h
)
@@ -0,0 +1,7 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
</assembly>
@@ -0,0 +1,13 @@
/*
* 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.
*
*/
IDI_ICON1 ICON DISCARDABLE "@ICON_FILE@"
@@ -0,0 +1,13 @@
#
# 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.
#
set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE APPLICATION)
@@ -0,0 +1,29 @@
/*
* 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.
*
*/
typedef unsigned long DWORD;
//Due to some laptops not auto-switching to the discrete GPU correctly we are adding these
//__declspec as defined in the AMD and NVidia white papers to 'force on' the use of the
//discrete chips. This will be overridden by users setting application profiles
//and may not work on older drivers or bios. In theory this should be enough to always force on
//the discrete chips.
//http://developer.download.nvidia.com/devzone/devcenter/gamegraphics/files/OptimusRenderingPolicies.pdf
//https://community.amd.com/thread/169965
// It is unclear if this is also needed for Linux or macOS at this time (22/02/2017)
extern "C"
{
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
}
@@ -0,0 +1,14 @@
/*
* 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 <Launcher_Traits_Windows.h>
@@ -0,0 +1,18 @@
/*
* 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
#define AZ_TRAIT_LAUNCHER_LOWER_CASE_PATHS 0
#define AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE 0
#define AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE 1
#define AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE 0
#define AZ_TRAIT_SHARED_LIBRARY_FILENAME_FORMAT R"(%s\%s.dll)"
@@ -0,0 +1,72 @@
/*
* 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 <Launcher.h>
#include <CryCommon/CryLibrary.h>
int APIENTRY WinMain([[maybe_unused]] HINSTANCE hInstance, [[maybe_unused]] HINSTANCE hPrevInstance, [[maybe_unused]] LPSTR lpCmdLine, [[maybe_unused]] int nCmdShow)
{
InitRootDir();
using namespace LumberyardLauncher;
PlatformMainInfo mainInfo;
mainInfo.m_instance = GetModuleHandle(0);
mainInfo.CopyCommandLine(__argc, __argv);
// Prevent allocator from growing in small chunks
// Pre-create our system allocator and configure it to ask for larger chunks from the OS
// Creating this here to be consistent with other platforms
AZ::SystemAllocator::Descriptor sysHeapDesc;
sysHeapDesc.m_heap.m_systemChunkSize = 64 * 1024 * 1024;
AZ::AllocatorInstance<AZ::SystemAllocator>::Create(sysHeapDesc);
ReturnCode status = Run(mainInfo);
#if !defined(_RELEASE)
bool noPrompt = (strstr(mainInfo.m_commandLine, "-noprompt") != nullptr);
#else
bool noPrompt = false;
#endif // !defined(_RELEASE)
if (!noPrompt && status != ReturnCode::Success)
{
MessageBoxA(0, GetReturnCodeString(status), "Error", MB_OK | MB_DEFAULT_DESKTOP_ONLY | MB_ICONERROR);
}
#if !defined(AZ_MONOLITHIC_BUILD)
{
// HACK HACK HACK - is this still needed?!?!
// CrySystem module can get loaded multiple times (even from within CrySystem itself)
// and currently there is no way to track them (\ref _CryMemoryManagerPoolHelper::Init() in CryMemoryManager_impl.h)
// so we will release it as many times as it takes until it actually unloads.
void* hModule = CryLoadLibraryDefName("CrySystem");
if (hModule)
{
// loop until we fail (aka unload the DLL)
while (CryFreeLibrary(hModule))
{
;
}
}
}
#endif // !defined(AZ_MONOLITHIC_BUILD)
// there is no way to transfer ownership of the allocator to the component application
// without altering the app descriptor, so it must be destroyed here
AZ::AllocatorInstance<AZ::SystemAllocator>::Destroy();
return static_cast<int>(status);
}
@@ -0,0 +1,14 @@
#
# 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.
#
set(FILES
Launcher_Game_Windows.cpp
)
@@ -0,0 +1,40 @@
#
# 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.
#
if (LY_MONOLITHIC_GAME) # only Atom is supported in monolithic
set(LY_BUILD_DEPENDENCIES
PUBLIC
Legacy::CryRenderOther
)
else()
set(LY_BUILD_DEPENDENCIES
PRIVATE
Legacy::CryRenderD3D11
)
endif()
# Find the resource from the game gem
get_target_property(${project}_GEM_DIR ${project} SOURCE_DIR) # Point to where the code is
get_filename_component(${project}_GEM_DIR ${${project}_GEM_DIR} DIRECTORY) # Parent directory
set(ICON_FILE ${${project}_GEM_DIR}/Resources/GameSDK.ico)
if(NOT EXISTS ${ICON_FILE})
# Try the common LauncherUnified icon instead
set(ICON_FILE Resources/GameSDK.ico)
endif()
if(EXISTS ${ICON_FILE})
set(target_file ${CMAKE_CURRENT_BINARY_DIR}/${project}.GameLauncher.rc)
configure_file(Platform/Windows/Launcher.rc.in
${target_file}
@ONLY
)
set(LY_FILES ${target_file})
endif()
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,16 @@
#
# 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.
#
set(FILES
Launcher_Windows.cpp
Launcher_Traits_Windows.h
Launcher_Traits_Platform.h
)
@@ -0,0 +1,13 @@
#
# 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.
#
set(PAL_TRAIT_LAUNCHERUNIFIED_LAUNCHER_TYPE APPLICATION)
@@ -0,0 +1,14 @@
/*
* 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 <Launcher_Traits_iOS.h>
@@ -0,0 +1,18 @@
/*
* 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
#define AZ_TRAIT_LAUNCHER_LOWER_CASE_PATHS 1
#define AZ_TRAIT_LAUNCHER_SET_APPROOT_OVERRIDE 1
#define AZ_TRAIT_LAUNCHER_ALLOW_CMDLINE_APPROOT_OVERRIDE 0
#define AZ_TRAIT_LAUNCHER_USE_CRY_DYNAMIC_MODULE_HANDLE 0
#define AZ_TRAIT_SHARED_LIBRARY_FILENAME_FORMAT "%s/lib%s.dylib"
@@ -0,0 +1,25 @@
/*
* 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.
*
*/
#import <UIKit/UIKit.h>
int main(int argc, char* argv[])
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
UIApplicationMain(argc,
argv,
@"LumberyardApplication_iOS",
@"LumberyardApplicationDelegate_iOS");
[pool release];
return 0;
}
@@ -0,0 +1,135 @@
/*
* 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 <Launcher.h>
#include <../Common/Apple/Launcher_Apple.h>
#include <../Common/UnixLike/Launcher_UnixLike.h>
#include <AzFramework/API/ApplicationAPI_Platform.h>
#include <AzCore/IO/SystemFile.h> // for AZ_MAX_PATH_LEN
#include <CrySystem/SystemUtilsApple.h>
#import <UIKit/UIKit.h>
namespace
{
const char* GetAppWriteStoragePath()
{
static char pathToApplicationPersistentStorage[AZ_MAX_PATH_LEN] = { 0 };
// Unlike Mac where we have unrestricted access to the filesystem, iOS apps are sandboxed such
// that you can only access a pre-defined set of directories.
// https://developer.apple.com/library/mac/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
SystemUtilsApple::GetPathToUserApplicationSupportDirectory(pathToApplicationPersistentStorage, AZ_MAX_PATH_LEN);
return pathToApplicationPersistentStorage;
}
}
@interface LumberyardApplicationDelegate_iOS : NSObject<UIApplicationDelegate>
{
}
@end // LumberyardApplicationDelegate_iOS Interface
@implementation LumberyardApplicationDelegate_iOS
- (int)runLumberyardApplication
{
#if AZ_TESTS_ENABLED
// TODO: iOS needs to determine how to get around being able to run in monolithic mode (ie no dynamic modules)
return static_cast<int>(ReturnCode::ErrUnitTestNotSupported);
#else
using namespace LumberyardLauncher;
PlatformMainInfo mainInfo;
mainInfo.m_updateResourceLimits = IncreaseResourceLimits;
mainInfo.m_appResourcesPath = GetAppResourcePath();
mainInfo.m_appWriteStoragePath = GetAppWriteStoragePath();
mainInfo.m_additionalVfsResolution = "\t- Check that usbmuxconnect is running and not reporting any errors when connecting to localhost";
NSArray* commandLine = [[NSProcessInfo processInfo] arguments];
for (size_t argIndex = 0; argIndex < [commandLine count]; ++argIndex)
{
NSString* arg = commandLine[argIndex];
if (!mainInfo.AddArgument([arg UTF8String]))
{
return static_cast<int>(ReturnCode::ErrCommandLine);
}
}
ReturnCode status = Run(mainInfo);
return static_cast<int>(status);
#endif // AZ_TESTS_ENABLED
}
- (void)launchLumberyardApplication
{
const int exitCode = [self runLumberyardApplication];
exit(exitCode);
}
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
// prevent the lumberyard runtime from running when launched in a xctest environment, otherwise the
// testing framework will kill the "app" due to the lengthy bootstrap process
if ([[NSProcessInfo processInfo] environment][@"XCTestConfigurationFilePath"] == nil)
{
[self performSelector:@selector(launchLumberyardApplication) withObject:nil afterDelay:0.0];
}
return YES;
}
- (void)applicationWillResignActive:(UIApplication*)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnWillResignActive);
}
- (void)applicationDidEnterBackground:(UIApplication*)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnDidEnterBackground);
}
- (void)applicationWillEnterForeground:(UIApplication*)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnWillEnterForeground);
}
- (void)applicationDidBecomeActive:(UIApplication*)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnDidBecomeActive);
}
- (void)applicationWillTerminate:(UIApplication *)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnWillTerminate);
}
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application
{
AzFramework::IosLifecycleEvents::Bus::Broadcast(
&AzFramework::IosLifecycleEvents::Bus::Events::OnDidReceiveMemoryWarning);
}
@end // LumberyardApplicationDelegate_iOS Implementation
@@ -0,0 +1,68 @@
/*
* 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.
*
*/
#import <UIKit/UIKit.h>
#include <AzFramework/Input/Buses/Notifications/RawInputNotificationBus_Platform.h>
@interface LumberyardApplication_iOS : UIApplication
{
}
@end // LumberyardApplication_iOS Interface
@implementation LumberyardApplication_iOS
- (void)touchesBegan: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
{
for (const UITouch* touch in touches)
{
AzFramework::RawInputNotificationBusIos::Broadcast(
&AzFramework::RawInputNotificationBusIos::Events::OnRawTouchEventBegan, touch);
}
}
- (void)touchesMoved: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
{
for (const UITouch* touch in touches)
{
AzFramework::RawInputNotificationBusIos::Broadcast(
&AzFramework::RawInputNotificationBusIos::Events::OnRawTouchEventMoved, touch);
}
}
- (void)touchesEnded: (NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
{
for (const UITouch* touch in touches)
{
AzFramework::RawInputNotificationBusIos::Broadcast(
&AzFramework::RawInputNotificationBusIos::Events::OnRawTouchEventEnded, touch);
}
}
- (void)touchesCancelled:(NSSet<UITouch*>*)touches withEvent: (UIEvent*)event
{
// Active touches can be cancelled (as opposed to ended) for a variety of reasons, including:
// - The active view being rotated to match the device orientation.
// - The application resigning it's active status (eg. when receiving a message or phone call).
// - Exceeding the max number of active touches tracked by the system (which as explained above
// is device dependent). For some reason this causes all active touches to be cancelled.
// In any case, for the purposes of a game (or really any application that I can think of),
// there really isn't any reason to distinguish between a touch ending or being cancelled.
// They are mutually exclusive events, and both result in the touch being discarded by the
// system.
[self touchesEnded: touches withEvent: event];
}
@end // LumberyardApplication_iOS Implementation
@@ -0,0 +1,11 @@
#
# 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.
#
@@ -0,0 +1,66 @@
#
# 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.
#
set(LY_LINK_OPTIONS
PRIVATE
-ObjC
)
if(LY_MONOLITHIC_GAME) # only Atom is supported in monolithic
list(APPEND LY_BUILD_DEPENDENCIES Legacy::CryRenderOther)
else()
list(APPEND LY_BUILD_DEPENDENCIES CrySystem.Static)
set(LY_RUNTIME_DEPENDENCIES Legacy::CryRenderMetal)
endif()
# Find the resource from the game gem
get_target_property(${project}_GEM_DIR ${project} SOURCE_DIR) # Point to where the code is
get_filename_component(${project}_GEM_DIR ${${project}_GEM_DIR} DIRECTORY) # Parent directory
set(ly_game_resource_folder ${${project}_GEM_DIR}/Resources/Platform/iOS)
if (NOT EXISTS ${ly_game_resource_folder})
set(ly_game_resource_folder ${${project}_GEM_DIR}/Resources/IOSLauncher)
if (NOT EXISTS ${ly_game_resource_folder})
message(FATAL_ERROR "Missing expected resources folder")
endif()
endif()
# Add resources and app icons to launchers
get_target_property(${project}_GEM_DIR ${project} SOURCE_DIR)
get_filename_component(${project}_GEM_DIR ${${project}_GEM_DIR} DIRECTORY)
target_sources(${project}.GameLauncher PRIVATE ${ly_game_resource_folder}/Images.xcassets)
set_target_properties(${project}.GameLauncher PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${ly_game_resource_folder}/Info.plist
RESOURCE ${ly_game_resource_folder}/Images.xcassets
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME ${project}AppIcon
)
set(layout_tool_dir ${LY_ROOT_FOLDER}/cmake/Tools)
add_custom_command(TARGET ${project}.GameLauncher POST_BUILD
COMMAND ${LY_PYTHON_CMD} layout_tool.py
--dev-root "${LY_ROOT_FOLDER}"
-p iOS
-a ${LY_ASSET_DEPLOY_ASSET_TYPE}
-g ${project}
-m ${LY_ASSET_DEPLOY_MODE}
--create-layout-root
-l $<TARGET_BUNDLE_DIR:${project}.GameLauncher>/assets
--build-config $<CONFIG>
--warn-on-missing-assets
--verify
--copy
${LY_OVERRIDE_PAK_ARGUMENT}
WORKING_DIRECTORY ${layout_tool_dir}
COMMENT "Synchronizing Layout Assets ..."
VERBATIM
)
@@ -0,0 +1,18 @@
#
# 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.
#
set(LY_BUILD_DEPENDENCIES
PUBLIC
3rdParty::LibTomCrypt
3rdParty::LibTomMath
3rdParty::FreeType2
)
@@ -0,0 +1,22 @@
#
# 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.
#
set(FILES
Launcher_iOS.mm
Launcher_Traits_iOS.h
Launcher_Traits_Platform.h
LumberyardApplication_iOS.mm
LumberyardApplicationDelegate_iOS.mm
../Common/Apple/Launcher_Apple.mm
../Common/Apple/Launcher_Apple.h
../Common/UnixLike/Launcher_UnixLike.cpp
../Common/UnixLike/Launcher_UnixLike.h
)
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:61efd8df621780af995fc1250918df5e00364ff00f849bef67702cd4b0a152e1
size 65537
+32
View File
@@ -0,0 +1,32 @@
/*
* 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 <AzCore/std/string/string_view.h>
namespace LumberyardLauncher
{
bool WaitForAssetProcessorConnect()
{
// Dedicated server does not depend on Asset Processor and assumes that assets are already prepared.
return false;
}
bool IsDedicatedServer()
{
return true;
}
const char* GetLogFilename()
{
return "@log@/Server.log";
}
}
+54
View File
@@ -0,0 +1,54 @@
/*
* 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.
*
*/
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// THIS CODE IS AUTOGENERATED, DO NOT MODIFY
/////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////
// This code creates AZ::Modules for use in a monolithic build.
#if AZ_MONOLITHIC_BUILD
#include <AzCore/std/containers/vector.h>
#define DECLARE_CRYREGISTER_SINGLETON_CLASS(implclassname) \
void* Get##implclassname##Factory();
DECLARE_CRYREGISTER_SINGLETON_CLASS(CEngineModule_Cry3DEngine)
DECLARE_CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryFont)
DECLARE_CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryNetwork)
DECLARE_CRYREGISTER_SINGLETON_CLASS(CEngineModule_CryRenderer)
#undef DECLARE_CRYREGISTER_SINGLETON_CLASS
namespace AZ
{
class Module;
}
${extern_module_declarations}
extern "C" void CreateStaticModules(AZStd::vector<AZ::Module*>& modulesOut)
{
${module_invocations}
// Call methods to avoid symbol striping
#define NON_STRIPPING_CALL(Module) \
AZ_UNUSED(Get##Module##Factory())
NON_STRIPPING_CALL(CEngineModule_Cry3DEngine);
NON_STRIPPING_CALL(CEngineModule_CryFont);
NON_STRIPPING_CALL(CEngineModule_CryNetwork);
NON_STRIPPING_CALL(CEngineModule_CryRenderer);
#undef NON_STRIPPING_CALL
}
#endif // AZ_MONOLITHIC_BUILD
@@ -0,0 +1,76 @@
/*
* 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 <AzTest/AzTest.h>
#include "../Launcher.h"
class UnifiedLauncherTestFixture
: public ::testing::Test
{
protected:
void SetUp() override {}
void TearDown() override {}
};
TEST_F(UnifiedLauncherTestFixture, PlatformMainInfoAddArgument_NoCommandLineFunctions_Success)
{
LumberyardLauncher::PlatformMainInfo test;
EXPECT_STREQ(test.m_commandLine, "");
EXPECT_EQ(test.m_argC, 0);
}
TEST_F(UnifiedLauncherTestFixture, PlatformMainInfoAddArgument_ValidParams_Success)
{
LumberyardLauncher::PlatformMainInfo test;
const char* testArguments[] = { "-arg", "value1", "-arg2", "value2", "-argspace", "value one"};
for (const char* testArgument : testArguments)
{
test.AddArgument(testArgument);
}
EXPECT_STREQ(test.m_commandLine, "-arg value1 -arg2 value2 -argspace \"value one\"");
EXPECT_EQ(test.m_argC, 6);
EXPECT_STREQ(test.m_argV[0], "-arg");
EXPECT_STREQ(test.m_argV[1], "value1");
EXPECT_STREQ(test.m_argV[2], "-arg2");
EXPECT_STREQ(test.m_argV[3], "value2");
EXPECT_STREQ(test.m_argV[4], "-argspace");
EXPECT_STREQ(test.m_argV[5], "value one");
}
TEST_F(UnifiedLauncherTestFixture, PlatformMainInfoCopyCommandLineArgCArgV_ValidParams_Success)
{
LumberyardLauncher::PlatformMainInfo test;
const char* constTestArguments[] = { "-arg", "value1", "-arg2", "value2", "-argspace", "value one" };
char** testArguments = const_cast<char**>(constTestArguments);
int testArgumentCount = AZ_ARRAY_SIZE(constTestArguments);
test.CopyCommandLine(testArgumentCount,testArguments);
EXPECT_STREQ(test.m_commandLine, "-arg value1 -arg2 value2 -argspace \"value one\"");
EXPECT_EQ(test.m_argC, 6);
EXPECT_STREQ(test.m_argV[0], "-arg");
EXPECT_STREQ(test.m_argV[1], "value1");
EXPECT_STREQ(test.m_argV[2], "-arg2");
EXPECT_STREQ(test.m_argV[3], "value2");
EXPECT_STREQ(test.m_argV[4], "-argspace");
EXPECT_STREQ(test.m_argV[5], "value one");
}
AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV);
+44
View File
@@ -0,0 +1,44 @@
/*
* 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 <AzCore/std/string/string_view.h>
namespace LumberyardLauncher
{
bool WaitForAssetProcessorConnect()
{
return false;
}
bool IsDedicatedServer()
{
return false;
}
const char* GetLogFilename()
{
return "@log@/Game.log";
}
const AZStd::string_view GetBuildTargetName()
{
#if !defined (LY_CMAKE_TARGET)
#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target"
#endif
return { LY_CMAKE_TARGET };
}
const AZStd::string_view GetGameProjectName()
{
return { "Tests" };
}
}
+15
View File
@@ -0,0 +1,15 @@
#
# 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.
#
set(FILES
Launcher.cpp
Launcher.h
)
@@ -0,0 +1,14 @@
#
# 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.
#
set(FILES
Game.cpp
)
@@ -0,0 +1,15 @@
#
# 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.
#
set(FILES
LauncherProject.cpp
StaticModules.in
)
@@ -0,0 +1,14 @@
#
# 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.
#
set(FILES
Server.cpp
)
@@ -0,0 +1,15 @@
#
# 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.
#
set(FILES
Tests/LauncherUnifiedTests.cpp
Tests/Test.cpp
)