Sfoglia il codice sorgente

Updated all relevant paths so that executable files can be placed in root directory of the built application, but also kept the old paths to keep the file structure while using non-packaged builds (e.g. debugging)

BearishSun 10 anni fa
parent
commit
0025c6b2dd

+ 1 - 0
BansheeCore/Source/BsUtility.cpp

@@ -1,5 +1,6 @@
 #include "BsUtility.h"
 #include "BsRTTIType.h"
+#include "BsFileSystem.h"
 
 namespace BansheeEngine
 {

+ 28 - 20
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -186,6 +186,16 @@ namespace BansheeEngine
 		 */
 		WString getEmptyCSScriptCode() const;
 
+		/**
+		 * @brief	Returns path to the builtin shader include folder, relative to the working directory.
+		 */
+		static Path getShaderIncludeFolder();
+
+		/**
+		 * @brief	Returns path to the default widget layout file, relative to the working directory.
+		 */
+		static Path getDefaultWidgetLayoutPath();
+
 		static const String ObjectFieldStyleName;
 		static const String ObjectFieldLabelStyleName;
 		static const String ObjectFieldDropBtnStyleName;
@@ -196,14 +206,6 @@ namespace BansheeEngine
 		static const String TextureFieldDropStyleName;
 		static const String TextureFieldClearBtnStyleName;
 
-		static const Path BuiltinDataFolder;
-		static const Path EditorSkinFolder;
-		static const Path EditorIconFolder;
-		static const Path EditorShaderFolder;
-		static const Path EditorShaderIncludeFolder;
-
-		static const Path DefaultWidgetLayoutPath;
-
 	private:
 		/**
 		 * @brief	Imports all necessary resources and converts them to engine-ready format.
@@ -227,17 +229,17 @@ namespace BansheeEngine
 		/**
 		 * @brief	Loads a GUI skin texture with the specified filename.
 		 */
-		static HSpriteTexture getGUITexture(const WString& name);
+		HSpriteTexture getGUITexture(const WString& name) const;
 
 		/**
 		 * @brief	Loads a GUI icon with the specified filename.
 		 */
-		static HSpriteTexture getGUIIcon(const WString& name);
+		HSpriteTexture getGUIIcon(const WString& name) const;
 
 		/**
 		 * @brief	Loads a shader with the specified filename
 		 */
-		static HShader getShader(const WString& name);
+		HShader getShader(const WString& name) const;
 
 		HShader mShaderDockOverlay;
 		HShader mShaderSceneGrid;
@@ -256,17 +258,23 @@ namespace BansheeEngine
 
 		ResourceManifestPtr mResourceManifest;
 
-		static const Path ShaderFolder;
-		static const Path SkinFolder;
-		static const Path IconFolder;
-		static const Path ShaderIncludeFolder;
+		static const char* ShaderFolder;
+		static const char* SkinFolder;
+		static const char* IconFolder;
+		static const char* ShaderIncludeFolder;
+
+		Path BuiltinDataFolder;
+		Path EditorSkinFolder;
+		Path EditorIconFolder;
+		Path EditorShaderFolder;
+		Path EditorShaderIncludeFolder;
 
-		static const Path BuiltinRawDataFolder;
-		static const Path EditorRawSkinFolder;
-		static const Path EditorRawShaderIncludeFolder;
-		static const Path EditorRawShaderFolder;
+		Path BuiltinRawDataFolder;
+		Path EditorRawSkinFolder;
+		Path EditorRawShaderIncludeFolder;
+		Path EditorRawShaderFolder;
 
-		static const Path ResourceManifestPath;
+		Path ResourceManifestPath;
 
 		static const WString DefaultFontFilename;
 		static const WString DefaultAAFontFilename;

+ 0 - 1
BansheeEditor/Include/BsEditorApplication.h

@@ -182,7 +182,6 @@ namespace BansheeEngine
 	private:
 		static const Path WIDGET_LAYOUT_PATH;
 		static const Path BUILD_DATA_PATH;
-		static const Path EDITOR_SETTINGS_PATH;
 		static const Path PROJECT_SETTINGS_PATH;
 
 		RenderAPIPlugin mActiveRAPIPlugin;

+ 12 - 14
BansheeEditor/Source/BsBuildManager.cpp

@@ -91,9 +91,17 @@ namespace BansheeEngine
 
 	Path BuildManager::getBuildFolder(BuildFolder folder, PlatformType platform) const
 	{
-		Path sourceRoot = APP_ROOT;
+		// Use Data folder as an anchor to find where the root is
+		Path sourceRoot = Paths::getRuntimeDataPath();
 		sourceRoot.makeAbsolute(FileSystem::getWorkingDirectoryPath());
 
+		UINT32 numDataDirs = Paths::RUNTIME_DATA_PATH.getNumDirectories();
+		if (Paths::RUNTIME_DATA_PATH.isFile())
+			numDataDirs++;
+
+		for (UINT32 i = 0; i < numDataDirs; i++)
+			sourceRoot.makeParent();
+
 		switch (folder)
 		{
 		case BuildFolder::SourceRoot:
@@ -115,19 +123,9 @@ namespace BansheeEngine
 			return binariesPath.makeRelative(sourceRoot);
 		}
 		case BuildFolder::BansheeAssemblies:
-		{
-			Path dataPath = ASSEMBLY_PATH;
-			dataPath.makeAbsolute(FileSystem::getWorkingDirectoryPath());
-
-			return dataPath.makeRelative(sourceRoot);
-		}
+			return Paths::ASSEMBLY_PATH;
 		case BuildFolder::Data:
-		{
-			Path dataPath = ENGINE_DATA_PATH;
-			dataPath.makeAbsolute(FileSystem::getWorkingDirectoryPath());
-
-			return dataPath.makeRelative(sourceRoot);
-		}
+			return Paths::ENGINE_DATA_PATH;
 		}
 
 		return Path::BLANK;
@@ -139,7 +137,7 @@ namespace BansheeEngine
 		{
 		case PlatformType::Windows:
 		{
-			Path output = RUNTIME_DATA_PATH + "Binaries\\Win64\\Game.exe";
+			Path output = Paths::getRuntimeDataPath() + "Binaries\\Win64\\Game.exe";
 			output.makeAbsolute(FileSystem::getWorkingDirectoryPath());
 
 			return output;

+ 38 - 23
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -50,6 +50,8 @@
 
 namespace BansheeEngine
 {
+	static const Path EDITOR_DATA_FOLDER = "Editor\\";
+
 	const String BuiltinEditorResources::ObjectFieldStyleName = "GUIObjectField";
 	const String BuiltinEditorResources::ObjectFieldLabelStyleName = "EditorFieldLabel";
 	const String BuiltinEditorResources::ObjectFieldDropBtnStyleName = "DropButton";
@@ -70,24 +72,10 @@ namespace BansheeEngine
 
 	const WString BuiltinEditorResources::GUISkinFile = L"GUISkin";
 
-	const Path BuiltinEditorResources::ShaderFolder = L"Shaders\\";
-	const Path BuiltinEditorResources::SkinFolder = L"Skin\\";
-	const Path BuiltinEditorResources::IconFolder = L"Skin\\Icons";
-	const Path BuiltinEditorResources::ShaderIncludeFolder = L"Includes\\";
-
-	const Path BuiltinEditorResources::BuiltinRawDataFolder = RUNTIME_DATA_PATH + L"Raw\\Editor\\";
-	const Path BuiltinEditorResources::EditorRawSkinFolder = BuiltinRawDataFolder + SkinFolder;
-	const Path BuiltinEditorResources::EditorRawShaderFolder = BuiltinRawDataFolder + ShaderFolder;
-	const Path BuiltinEditorResources::EditorRawShaderIncludeFolder = BuiltinRawDataFolder + ShaderIncludeFolder;
-
-	const Path BuiltinEditorResources::BuiltinDataFolder = RUNTIME_DATA_PATH + L"Editor\\";
-	const Path BuiltinEditorResources::EditorSkinFolder = BuiltinDataFolder + SkinFolder;
-	const Path BuiltinEditorResources::EditorIconFolder = BuiltinDataFolder + IconFolder;
-	const Path BuiltinEditorResources::EditorShaderFolder = BuiltinDataFolder + ShaderFolder;
-	const Path BuiltinEditorResources::EditorShaderIncludeFolder = BuiltinDataFolder + ShaderIncludeFolder;
-
-	const Path BuiltinEditorResources::ResourceManifestPath = BuiltinDataFolder + "ResourceManifest.asset";
-	const Path BuiltinEditorResources::DefaultWidgetLayoutPath = BuiltinDataFolder + "Layout.asset";
+	const char* BuiltinEditorResources::ShaderFolder = "Shaders\\";
+	const char* BuiltinEditorResources::SkinFolder = "Skin\\";
+	const char* BuiltinEditorResources::IconFolder = "Skin\\Icons";
+	const char* BuiltinEditorResources::ShaderIncludeFolder = "Includes\\";
 
 	const WString BuiltinEditorResources::FolderIconTex = L"FolderIcon.psd";
 	const WString BuiltinEditorResources::MeshIconTex = L"MeshIcon.psd";
@@ -302,10 +290,25 @@ namespace BansheeEngine
 
 	BuiltinEditorResources::BuiltinEditorResources()
 	{
+		// Set up paths
+		BuiltinRawDataFolder = Paths::getRuntimeDataPath() + L"Raw\\Editor\\";
+		EditorRawSkinFolder = BuiltinRawDataFolder + SkinFolder;
+		EditorRawShaderFolder = BuiltinRawDataFolder + ShaderFolder;
+		EditorRawShaderIncludeFolder = BuiltinRawDataFolder + ShaderIncludeFolder;
+
+		BuiltinDataFolder = Paths::getRuntimeDataPath() + EDITOR_DATA_FOLDER;
+		EditorSkinFolder = BuiltinDataFolder + SkinFolder;
+		EditorIconFolder = BuiltinDataFolder + IconFolder;
+		EditorShaderFolder = BuiltinDataFolder + ShaderFolder;
+		EditorShaderIncludeFolder = BuiltinDataFolder + ShaderIncludeFolder;
+
+		ResourceManifestPath = BuiltinDataFolder + "ResourceManifest.asset";
+
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
 		absoluteDataPath.append(BuiltinDataFolder);
 
-//#if BS_DEBUG_MODE
+		// Update from raw assets if needed
+#if BS_DEBUG_MODE
 		if (BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + L"Timestamp.asset"))
 		{
 			mResourceManifest = ResourceManifest::create("BuiltinResources");
@@ -319,8 +322,9 @@ namespace BansheeEngine
 
 			ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 		}
-//#endif
+#endif
 
+		// Load manifest
 		if (mResourceManifest == nullptr)
 		{
 			if (FileSystem::exists(ResourceManifestPath))
@@ -332,6 +336,7 @@ namespace BansheeEngine
 			gResources().registerResourceManifest(mResourceManifest);
 		}
 
+		// Load basic resources
 		mShaderDockOverlay = getShader(ShaderDockOverlayFile);
 		mShaderSceneGrid = getShader(ShaderSceneGridFile);
 		mShaderPicking[(int)CULL_NONE] = getShader(ShaderPickingCullNoneFile);
@@ -1851,7 +1856,7 @@ namespace BansheeEngine
 		return skin;
 	}
 
-	HSpriteTexture BuiltinEditorResources::getGUITexture(const WString& name)
+	HSpriteTexture BuiltinEditorResources::getGUITexture(const WString& name) const
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		texturePath.append(EditorSkinFolder);
@@ -1860,7 +1865,7 @@ namespace BansheeEngine
 		return gResources().load<SpriteTexture>(texturePath);
 	}
 
-	HSpriteTexture BuiltinEditorResources::getGUIIcon(const WString& name)
+	HSpriteTexture BuiltinEditorResources::getGUIIcon(const WString& name) const
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		texturePath.append(EditorIconFolder);
@@ -1869,7 +1874,7 @@ namespace BansheeEngine
 		return gResources().load<SpriteTexture>(texturePath);
 	}
 
-	HShader BuiltinEditorResources::getShader(const WString& name)
+	HShader BuiltinEditorResources::getShader(const WString& name) const
 	{
 		Path programPath = EditorShaderFolder;
 		programPath.append(name + L".asset");
@@ -2227,4 +2232,14 @@ namespace BansheeEngine
 
 		return StringUtil::WBLANK;
 	}
+
+	Path BuiltinEditorResources::getShaderIncludeFolder()
+	{
+		return Paths::getRuntimeDataPath() + EDITOR_DATA_FOLDER + ShaderIncludeFolder;
+	}
+
+	Path BuiltinEditorResources::getDefaultWidgetLayoutPath()
+	{
+		return Paths::getRuntimeDataPath() + EDITOR_DATA_FOLDER + "Layout.asset";
+	}
 }

+ 8 - 4
BansheeEditor/Source/BsEditorApplication.cpp

@@ -32,7 +32,6 @@ namespace BansheeEngine
 {
 	const Path EditorApplication::WIDGET_LAYOUT_PATH = PROJECT_INTERNAL_DIR + L"Layout.asset";
 	const Path EditorApplication::BUILD_DATA_PATH = PROJECT_INTERNAL_DIR + L"BuildData.asset";
-	const Path EditorApplication::EDITOR_SETTINGS_PATH = RUNTIME_DATA_PATH + L"Settings.asset";
 	const Path EditorApplication::PROJECT_SETTINGS_PATH = PROJECT_INTERNAL_DIR + L"Settings.asset";
 
 	RENDER_WINDOW_DESC createRenderWindowDesc()
@@ -59,6 +58,11 @@ namespace BansheeEngine
 		return importers;
 	}
 
+	Path getEditorSettingsPath()
+	{
+		return Paths::getRuntimeDataPath() + L"Settings.asset";
+	}
+
 	EditorApplication::EditorApplication(EditorRenderAPI renderAPIPlugin)
 		:Application(createRenderWindowDesc(), toEngineRenderAPI(renderAPIPlugin), RendererPlugin::Default, getImporters()),
 		mActiveRAPIPlugin(toEngineRenderAPI(renderAPIPlugin)), mSBansheeEditorPlugin(nullptr), mIsProjectLoaded(false)
@@ -279,7 +283,7 @@ namespace BansheeEngine
 			FileSystem::createDir(internalResourcesDir);
 
 		Path defaultLayoutPath = FileSystem::getWorkingDirectoryPath();
-		defaultLayoutPath.append(BuiltinEditorResources::DefaultWidgetLayoutPath);
+		defaultLayoutPath.append(BuiltinEditorResources::getDefaultWidgetLayoutPath());
 
 		if (FileSystem::exists(defaultLayoutPath))
 		{
@@ -325,7 +329,7 @@ namespace BansheeEngine
 	void EditorApplication::loadEditorSettings()
 	{
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(EDITOR_SETTINGS_PATH);
+		absoluteDataPath.append(getEditorSettingsPath());
 
 		if (FileSystem::exists(absoluteDataPath))
 		{
@@ -343,7 +347,7 @@ namespace BansheeEngine
 			return;
 
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(EDITOR_SETTINGS_PATH);
+		absoluteDataPath.append(getEditorSettingsPath());
 
 		FileEncoder fs(absoluteDataPath);
 		fs.encode(mEditorSettings.get());

+ 2 - 2
BansheeEditor/Source/BsShaderIncludeHandler.cpp

@@ -38,7 +38,7 @@ namespace BansheeEngine
 		{
 			if (name.size() > 8)
 			{
-				Path fullPath = BuiltinResources::EngineShaderIncludeFolder;
+				Path fullPath = BuiltinResources::getShaderIncludeFolder();
 				Path includePath = name.substr(9, name.size() - 9);
 
 				fullPath.append(includePath);
@@ -51,7 +51,7 @@ namespace BansheeEngine
 		{
 			if (name.size() > 8)
 			{
-				Path fullPath = BuiltinEditorResources::EditorShaderIncludeFolder;
+				Path fullPath = BuiltinEditorResources::getShaderIncludeFolder();
 				Path includePath = name.substr(9, name.size() - 9);
 
 				fullPath.append(includePath);

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

@@ -282,6 +282,7 @@
     <ClCompile Include="Source\BsVirtualInput.cpp" />
     <ClCompile Include="Source\BsLight.cpp" />
     <ClCompile Include="Source\BsGameSettings.cpp" />
+    <ClCompile Include="Source\BsPaths.cpp" />
     <ClInclude Include="Include\BsApplication.h" />
     <ClInclude Include="Include\BsCamera.h" />
     <ClInclude Include="Include\BsCameraRTTI.h" />
@@ -391,6 +392,7 @@
     <ClCompile Include="Source\BsGUIContextMenu.cpp" />
     <ClInclude Include="Include\BsVirtualInput.h" />
     <ClInclude Include="Include\BsProfilerOverlayRTTI.h" />
+    <ClInclude Include="Include\BsPaths.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsApplication.cpp" />

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -362,6 +362,9 @@
     <ClInclude Include="Include\BsGameSettingsRTTI.h">
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsPaths.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -619,5 +622,8 @@
     <ClCompile Include="Source\BsGameSettings.cpp">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsPaths.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 36 - 25
BansheeEngine/Include/BsBuiltinResources.h

@@ -121,20 +121,23 @@ namespace BansheeEngine
 		 * 
 		 * @param	Path relative to the default shader folder with no file extension.
 		 */
-		static HShader getShader(const Path& path);
+		HShader getShader(const Path& path);
 
 		/**
 		 * @brief	Returns image data the Banshee Engine splash screen.
 		 */
 		static PixelDataPtr getSplashScreen();
 
-		static const Path BuiltinDataFolder;
-		static const Path EngineSkinFolder;
-		static const Path EngineCursorFolder;
-		static const Path EngineIconFolder;
-		static const Path EngineShaderFolder;
-		static const Path EngineShaderIncludeFolder;
-		static const Path EngineMeshFolder;
+		/**
+		 * @brief	Returns path to the builtin shader include folder, relative to the working directory.
+		 */
+		static Path getShaderIncludeFolder();
+
+		/**
+		 * @brief	Returns path to the builtin icons folder, relative to the working directory.
+		 */
+		static Path getIconFolder();
+
 		static const WString IconTextureName;
 	private:
 		/**
@@ -158,12 +161,12 @@ namespace BansheeEngine
 		/**
 		 * @brief	Loads a GUI skin texture with the specified filename.
 		 */
-		static HSpriteTexture getSkinTexture(const WString& name);
+		HSpriteTexture getSkinTexture(const WString& name);
 
 		/**
 		 * @brief	Loads a cursor texture with the specified filename.
 		 */
-		static HTexture getCursorTexture(const WString& name);
+		HTexture getCursorTexture(const WString& name);
 
 		HGUISkin mSkin;
 
@@ -188,21 +191,29 @@ namespace BansheeEngine
 
 		ResourceManifestPtr mResourceManifest;
 
-		static const Path BuiltinRawDataFolder;
-		static const Path EngineRawCursorFolder;
-		static const Path EngineRawIconFolder;
-		static const Path EngineRawShaderFolder;
-		static const Path EngineRawShaderIncludeFolder;
-		static const Path EngineRawSkinFolder;
-
-		static const Path CursorFolder;
-		static const Path IconFolder;
-		static const Path ShaderFolder;
-		static const Path ShaderIncludeFolder;
-		static const Path SkinFolder;
-		static const Path MeshFolder;
-
-		static const Path ResourceManifestPath;
+		Path mBuiltinRawDataFolder;
+		Path mEngineRawCursorFolder;
+		Path mEngineRawIconFolder;
+		Path mEngineRawShaderFolder;
+		Path mEngineRawShaderIncludeFolder;
+		Path mEngineRawSkinFolder;
+
+		Path mBuiltinDataFolder;
+		Path mEngineSkinFolder;
+		Path mEngineCursorFolder;
+		Path mEngineIconFolder;
+		Path mEngineShaderFolder;
+		Path mEngineShaderIncludeFolder;
+		Path mEngineMeshFolder;
+
+		Path ResourceManifestPath;
+
+		static const char* CursorFolder;
+		static const char* IconFolder;
+		static const char* ShaderFolder;
+		static const char* ShaderIncludeFolder;
+		static const char* SkinFolder;
+		static const char* MeshFolder;
 
 		static const WString DefaultFontFilename;
 		static const UINT32 DefaultFontSize;

+ 56 - 0
BansheeEngine/Include/BsPaths.h

@@ -0,0 +1,56 @@
+#pragma once
+
+namespace BansheeEngine
+{
+	static const char* ENGINE_ASSEMBLY = "MBansheeEngine";
+	static const char* SCRIPT_GAME_ASSEMBLY = "MScriptGame";
+	static const char* GAME_RESOURCES_FOLDER_NAME = "Resources\\";
+	static const char* GAME_SETTINGS_NAME = "GameSettings.asset";
+	static const char* GAME_RESOURCE_MANIFEST_NAME = "ResourceManifest.asset";
+
+	/**
+	 * @brief	Contains common engine paths.
+	 */
+	class BS_EXPORT Paths
+	{
+	public:
+		/**
+		 * @brief	Returns a path where the managed assemblies are located. Relative to working directory.
+		 */
+		static const Path& getAssemblyPath();
+
+		/**
+		 * @brief	Returns a path where the builtin assets are located. Relative to working directory.
+		 */
+		static const Path& getRuntimeDataPath();
+
+		/**
+		 * @brief	Returns a path where the builtin engine-specific assets are located. Relative to working directory.
+		 */
+		static const Path& getEngineDataPath();
+
+		/**
+		 * @brief	Returns a path to the game settings file used by editor-built executables. Relative to working directory.
+		 */
+		static const Path& getGameSettingsPath();
+
+		/**
+		 * @brief	Returns a path to the game resources folder used by editor-built executables. Relative to working directory.
+		 */
+		static const Path& getGameResourcesPath();
+
+		/**
+		 * @brief	Searches common locations for a specified path by querying if the file/directory exists and 
+		 * 			returns the found path.
+		 * 			
+		 * @param	path	Relative path to search for (e.g. "Data\").
+		 * 					
+		 * @returns	Path at which the relative path was found at. This path will be relative to the working directory.
+		 */
+		static Path findPath(const Path& path);
+
+		static const Path ASSEMBLY_PATH;
+		static const Path RUNTIME_DATA_PATH;
+		static const Path ENGINE_DATA_PATH;
+	};
+}

+ 1 - 12
BansheeEngine/Include/BsPrerequisites.h

@@ -21,6 +21,7 @@
 #include "BsGameObject.h"
 #include "BsEnums.h"
 #include "BsHEString.h"
+#include "BsPaths.h"
 
 namespace BansheeEngine
 {
@@ -130,18 +131,6 @@ namespace BansheeEngine
 	typedef ResourceHandle<ScriptCode> HScriptCode;
 	typedef ResourceHandle<GUISkin> HGUISkin;
 
-	static const char* ENGINE_ASSEMBLY = "MBansheeEngine";
-	static const char* SCRIPT_GAME_ASSEMBLY = "MScriptGame";
-	static const Path ASSEMBLY_PATH = "..\\..\\Assemblies\\";
-	static const Path APP_ROOT = "..\\..\\..\\";
-	static const char* GAME_RESOURCES_FOLDER_NAME = "Resources\\";
-	static const Path GAME_RESOURCES_PATH = APP_ROOT + GAME_RESOURCES_FOLDER_NAME;
-	static const Path RUNTIME_DATA_PATH = APP_ROOT + "Data\\";
-	static const Path ENGINE_DATA_PATH = RUNTIME_DATA_PATH + "Engine\\";
-	static const char* GAME_SETTINGS_NAME = "GameSettings.asset";
-	static const Path GAME_SETTINGS_PATH = APP_ROOT + GAME_SETTINGS_NAME;
-	static const char* GAME_RESOURCE_MANIFEST_NAME = "ResourceManifest.asset";
-
 	/**
 	 * @brief	RTTI types.
 	 */

+ 2 - 2
BansheeEngine/Source/BsApplication.cpp

@@ -160,7 +160,7 @@ namespace BansheeEngine
 	Path Application::getBuiltinAssemblyFolder() const
 	{
 		Path assemblyFolder = FileSystem::getWorkingDirectoryPath();
-		assemblyFolder.append(ASSEMBLY_PATH);
+		assemblyFolder.append(Paths::getAssemblyPath());
 
 		return assemblyFolder;
 	}
@@ -168,7 +168,7 @@ namespace BansheeEngine
 	Path Application::getScriptAssemblyFolder() const
 	{
 		Path assemblyFolder = FileSystem::getWorkingDirectoryPath();
-		assemblyFolder.append(ASSEMBLY_PATH);
+		assemblyFolder.append(Paths::getAssemblyPath());
 
 		return assemblyFolder;
 	}

+ 61 - 47
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -45,29 +45,12 @@ namespace BansheeEngine
 
 	const WString BuiltinResources::GUISkinFile = L"GUISkin";
 
-	const Path BuiltinResources::CursorFolder = L"Cursors\\";
-	const Path BuiltinResources::IconFolder = L"Icons\\";
-	const Path BuiltinResources::ShaderFolder = L"Shaders\\";
-	const Path BuiltinResources::SkinFolder = L"Skin\\";
-	const Path BuiltinResources::ShaderIncludeFolder = L"Includes\\";
-	const Path BuiltinResources::MeshFolder = L"Meshes\\";
-
-	const Path BuiltinResources::BuiltinRawDataFolder = RUNTIME_DATA_PATH + L"Raw\\Engine\\";
-	const Path BuiltinResources::EngineRawSkinFolder = BuiltinRawDataFolder + SkinFolder;
-	const Path BuiltinResources::EngineRawCursorFolder = BuiltinRawDataFolder + CursorFolder;
-	const Path BuiltinResources::EngineRawIconFolder = BuiltinRawDataFolder + IconFolder;
-	const Path BuiltinResources::EngineRawShaderFolder = BuiltinRawDataFolder + ShaderFolder;
-	const Path BuiltinResources::EngineRawShaderIncludeFolder = BuiltinRawDataFolder + ShaderIncludeFolder;
-
-	const Path BuiltinResources::BuiltinDataFolder = ENGINE_DATA_PATH;
-	const Path BuiltinResources::EngineSkinFolder = BuiltinDataFolder + SkinFolder;
-	const Path BuiltinResources::EngineCursorFolder = BuiltinDataFolder + CursorFolder;
-	const Path BuiltinResources::EngineIconFolder = BuiltinDataFolder + IconFolder;
-	const Path BuiltinResources::EngineShaderFolder = BuiltinDataFolder + ShaderFolder;
-	const Path BuiltinResources::EngineShaderIncludeFolder = BuiltinDataFolder + ShaderIncludeFolder;
-	const Path BuiltinResources::EngineMeshFolder = BuiltinDataFolder + MeshFolder;
-
-	const Path BuiltinResources::ResourceManifestPath = BuiltinDataFolder + "ResourceManifest.asset";
+	const char* BuiltinResources::CursorFolder = "Cursors\\";
+	const char* BuiltinResources::IconFolder = "Icons\\";
+	const char* BuiltinResources::ShaderFolder = "Shaders\\";
+	const char* BuiltinResources::SkinFolder = "Skin\\";
+	const char* BuiltinResources::ShaderIncludeFolder = "Includes\\";
+	const char* BuiltinResources::MeshFolder = "Meshes\\";
 
 	/************************************************************************/
 	/* 								GUI TEXTURES                      		*/
@@ -206,8 +189,27 @@ namespace BansheeEngine
 
 	BuiltinResources::BuiltinResources()
 	{
+		// Set up paths
+		mBuiltinRawDataFolder = Paths::getRuntimeDataPath() + L"Raw\\Engine\\";
+		mEngineRawSkinFolder = mBuiltinRawDataFolder + SkinFolder;
+		mEngineRawCursorFolder = mBuiltinRawDataFolder + CursorFolder;
+		mEngineRawIconFolder = mBuiltinRawDataFolder + IconFolder;
+		mEngineRawShaderFolder = mBuiltinRawDataFolder + ShaderFolder;
+		mEngineRawShaderIncludeFolder = mBuiltinRawDataFolder + ShaderIncludeFolder;
+
+		mBuiltinDataFolder = Paths::getEngineDataPath();
+		mEngineSkinFolder = mBuiltinDataFolder + SkinFolder;
+		mEngineCursorFolder = mBuiltinDataFolder + CursorFolder;
+		mEngineIconFolder = mBuiltinDataFolder + IconFolder;
+		mEngineShaderFolder = mBuiltinDataFolder + ShaderFolder;
+		mEngineShaderIncludeFolder = mBuiltinDataFolder + ShaderIncludeFolder;
+		mEngineMeshFolder = mBuiltinDataFolder + MeshFolder;
+
+		ResourceManifestPath = mBuiltinDataFolder + "ResourceManifest.asset";
+
+		// Load manifest
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(BuiltinDataFolder);
+		absoluteDataPath.append(mBuiltinDataFolder);
 
 		if (FileSystem::exists(ResourceManifestPath))
 			mResourceManifest = ResourceManifest::load(ResourceManifestPath, absoluteDataPath);
@@ -217,22 +219,24 @@ namespace BansheeEngine
 
 		gResources().registerResourceManifest(mResourceManifest);
 
+		// Update from raw assets if needed
 #if BS_DEBUG_MODE
-		if (FileSystem::exists(BuiltinRawDataFolder))
+		if (FileSystem::exists(mBuiltinRawDataFolder))
 		{
-			if (BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + L"Timestamp.asset"))
+			if (BuiltinResourcesHelper::checkForModifications(mBuiltinRawDataFolder, mBuiltinDataFolder + L"Timestamp.asset"))
 			{
 				preprocess();
-				BuiltinResourcesHelper::writeTimestamp(BuiltinDataFolder + L"Timestamp.asset");
+				BuiltinResourcesHelper::writeTimestamp(mBuiltinDataFolder + L"Timestamp.asset");
 
 				Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-				absoluteDataPath.append(BuiltinDataFolder);
+				absoluteDataPath.append(mBuiltinDataFolder);
 
 				ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 			}
 		}
 #endif
 		
+		// Load basic resources
 		mShaderSpriteText = getShader(ShaderSpriteTextFile);
 		mShaderSpriteImage = getShader(ShaderSpriteImageAlphaFile);
 		mShaderSpriteNonAlphaImage = getShader(ShaderSpriteImageNoAlphaFile);
@@ -240,7 +244,7 @@ namespace BansheeEngine
 
 		mWhiteSpriteTexture = getSkinTexture(WhiteTex);
 
-		mSkin = gResources().load<GUISkin>(BuiltinDataFolder + (GUISkinFile + L".asset"));
+		mSkin = gResources().load<GUISkin>(mBuiltinDataFolder + (GUISkinFile + L".asset"));
 
 		/************************************************************************/
 		/* 								CURSOR		                     		*/
@@ -292,7 +296,7 @@ namespace BansheeEngine
 		/************************************************************************/
 
 		Path iconPath = FileSystem::getWorkingDirectoryPath();
-		iconPath.append(EngineIconFolder);
+		iconPath.append(mEngineIconFolder);
 		iconPath.append(IconTextureName + L".asset");
 
 		HTexture iconTex = gResources().load<Texture>(iconPath);
@@ -305,20 +309,20 @@ namespace BansheeEngine
 
 	void BuiltinResources::preprocess()
 	{
-		BuiltinResourcesHelper::importAssets(EngineRawCursorFolder, EngineCursorFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(EngineRawIconFolder, EngineIconFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(EngineRawShaderIncludeFolder, EngineShaderIncludeFolder, mResourceManifest); // Hidden dependency: Includes must be imported before shaders
-		BuiltinResourcesHelper::importAssets(EngineRawShaderFolder, EngineShaderFolder, mResourceManifest);
-		BuiltinResourcesHelper::importAssets(EngineRawSkinFolder, EngineSkinFolder, mResourceManifest);
+		BuiltinResourcesHelper::importAssets(mEngineRawCursorFolder, mEngineCursorFolder, mResourceManifest);
+		BuiltinResourcesHelper::importAssets(mEngineRawIconFolder, mEngineIconFolder, mResourceManifest);
+		BuiltinResourcesHelper::importAssets(mEngineRawShaderIncludeFolder, mEngineShaderIncludeFolder, mResourceManifest); // Hidden dependency: Includes must be imported before shaders
+		BuiltinResourcesHelper::importAssets(mEngineRawShaderFolder, mEngineShaderFolder, mResourceManifest);
+		BuiltinResourcesHelper::importAssets(mEngineRawSkinFolder, mEngineSkinFolder, mResourceManifest);
 
 		// Import font
-		BuiltinResourcesHelper::importFont(BuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, BuiltinDataFolder,
+		BuiltinResourcesHelper::importFont(mBuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, mBuiltinDataFolder,
 			{ DefaultFontSize }, false, mResourceManifest);
 
 		// Import splash screen
 		{
-			Path inputPath = BuiltinRawDataFolder + WString(SplashScreenName);
-			Path outputPath = BuiltinDataFolder + (WString(SplashScreenName) + L".asset");
+			Path inputPath = mBuiltinRawDataFolder + WString(SplashScreenName);
+			Path outputPath = mBuiltinDataFolder + (WString(SplashScreenName) + L".asset");
 
 			auto textureIO = gImporter().createImportOptions<TextureImportOptions>(inputPath);
 			textureIO->setCPUReadable(true);
@@ -332,12 +336,12 @@ namespace BansheeEngine
 		}
 
 		// Generate & save GUI sprite textures
-		BuiltinResourcesHelper::generateSpriteTextures(EngineSkinFolder, mResourceManifest);
+		BuiltinResourcesHelper::generateSpriteTextures(mEngineSkinFolder, mResourceManifest);
 
 		// Generate & save GUI skin
 		{
 			HGUISkin skin = generateGUISkin();
-			Path outputPath = FileSystem::getWorkingDirectoryPath() + BuiltinDataFolder + (GUISkinFile + L".asset");
+			Path outputPath = FileSystem::getWorkingDirectoryPath() + mBuiltinDataFolder + (GUISkinFile + L".asset");
 			Resources::instance().save(skin, outputPath, true);
 			mResourceManifest->registerResource(skin.getUUID(), outputPath);
 		}
@@ -351,7 +355,7 @@ namespace BansheeEngine
 	HGUISkin BuiltinResources::generateGUISkin()
 	{
 		Path fontPath = FileSystem::getWorkingDirectoryPath();
-		fontPath.append(BuiltinDataFolder);
+		fontPath.append(mBuiltinDataFolder);
 		fontPath.append(DefaultFontFilename + L".asset");
 
 		HFont font = gResources().load<Font>(fontPath);
@@ -808,7 +812,7 @@ namespace BansheeEngine
 		HMesh discMesh = Mesh::create(discMeshData);
 
 		// Save all meshes
-		Path outputDir = FileSystem::getWorkingDirectoryPath() + EngineMeshFolder;
+		Path outputDir = FileSystem::getWorkingDirectoryPath() + mEngineMeshFolder;
 
 		Path meshPath = outputDir + MeshBoxFile;
 		Resources::instance().save(boxMesh, meshPath, true);
@@ -834,7 +838,7 @@ namespace BansheeEngine
 	HSpriteTexture BuiltinResources::getSkinTexture(const WString& name)
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
-		texturePath.append(EngineSkinFolder);
+		texturePath.append(mEngineSkinFolder);
 		texturePath.append(L"sprite_" + name + L".asset");
 
 		return gResources().load<SpriteTexture>(texturePath);
@@ -842,7 +846,7 @@ namespace BansheeEngine
 
 	HShader BuiltinResources::getShader(const Path& path)
 	{
-		Path programPath = EngineShaderFolder;
+		Path programPath = mEngineShaderFolder;
 		programPath.append(path);
 		programPath.setExtension(programPath.getExtension() + ".asset");
 
@@ -852,7 +856,7 @@ namespace BansheeEngine
 	HTexture BuiltinResources::getCursorTexture(const WString& name)
 	{
 		Path cursorPath = FileSystem::getWorkingDirectoryPath();
-		cursorPath.append(EngineCursorFolder);
+		cursorPath.append(mEngineCursorFolder);
 		cursorPath.append(name + L".asset");
 
 		return gResources().load<Texture>(cursorPath);
@@ -925,16 +929,26 @@ namespace BansheeEngine
 
 	PixelDataPtr BuiltinResources::getSplashScreen()
 	{
-		Path splashScreenPath = BuiltinDataFolder + (WString(SplashScreenName) + L".asset");
+		Path splashScreenPath = Paths::getEngineDataPath() + (WString(SplashScreenName) + L".asset");
 		FileDecoder fd(splashScreenPath);
 
 		return std::static_pointer_cast<PixelData>(fd.decode());
 	}
 
+	Path BuiltinResources::getShaderIncludeFolder()
+	{
+		return Paths::getEngineDataPath() + ShaderIncludeFolder;
+	}
+
+	Path BuiltinResources::getIconFolder()
+	{
+		return Paths::getEngineDataPath() + IconFolder;
+	}
+
 	HMesh BuiltinResources::getMesh(BuiltinMesh mesh) const
 	{
 		Path meshPath = FileSystem::getWorkingDirectoryPath();
-		meshPath.append(EngineMeshFolder);
+		meshPath.append(mEngineMeshFolder);
 
 		switch (mesh)
 		{

+ 55 - 0
BansheeEngine/Source/BsPaths.cpp

@@ -0,0 +1,55 @@
+#include "BsPrerequisites.h"
+#include "BsFileSystem.h"
+
+namespace BansheeEngine
+{
+	static const Path RAW_APP_ROOT = "..\\..\\..\\"; // Path to the application root when files haven't been packaged yet (e.g. running from debugger)
+
+	const Path Paths::ASSEMBLY_PATH = "bin\\Assemblies\\";
+	const Path Paths::RUNTIME_DATA_PATH = "Data\\";
+	const Path Paths::ENGINE_DATA_PATH = RUNTIME_DATA_PATH + "Engine\\";
+
+	const Path& Paths::getAssemblyPath()
+	{
+		static Path path = findPath(ASSEMBLY_PATH);
+		return path;
+	}
+
+	const Path& Paths::getRuntimeDataPath()
+	{
+		static Path path = findPath(RUNTIME_DATA_PATH);
+		return path;
+	}
+
+	const Path& Paths::getEngineDataPath()
+	{
+		static Path path = findPath(ENGINE_DATA_PATH);
+		return path;
+	}
+
+	const Path& Paths::getGameSettingsPath()
+	{
+		static Path path = findPath(GAME_SETTINGS_NAME);
+		return path;
+	}
+
+	const Path& Paths::getGameResourcesPath()
+	{
+		static Path path = findPath(GAME_RESOURCES_FOLDER_NAME);
+		return path;
+	}
+
+	Path Paths::findPath(const Path& path)
+	{
+		if (FileSystem::exists(path))
+			return path;
+
+		Path output = path;
+		output.makeAbsolute(RAW_APP_ROOT);
+		if (FileSystem::exists(output))
+			return output;
+
+		// No path found, but return the initial value by default
+		return path;
+	}
+}

+ 13 - 8
BansheeMono/Source/BsMonoManager.cpp

@@ -5,6 +5,7 @@
 #include "BsMonoClass.h"
 #include "BsMonoUtil.h"
 #include "BsFileSystem.h"
+#include "BsApplication.h"
 
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/mono-config.h>
@@ -13,9 +14,9 @@
 
 namespace BansheeEngine
 {
-	const String MONO_LIB_DIR = "..\\..\\Mono\\lib\\";
-	const String MONO_ETC_DIR = "..\\..\\Mono\\etc\\";
-	const String MONO_COMPILER_DIR = "..\\..\\Mono\\compiler\\";
+	const String MONO_LIB_DIR = "bin\\Mono\\lib\\";
+	const String MONO_ETC_DIR = "bin\\Mono\\etc\\";
+	const String MONO_COMPILER_DIR = "bin\\Mono\\compiler\\";
 	const MonoVersion MONO_VERSION = MonoVersion::v4_5;
 	
 	struct MonoVersionData
@@ -33,8 +34,12 @@ namespace BansheeEngine
 	MonoManager::MonoManager()
 		:mRootDomain(nullptr), mScriptDomain(nullptr), mIsCoreLoaded(false)
 	{
-		mono_set_dirs(MONO_LIB_DIR.c_str(), MONO_ETC_DIR.c_str());
-		mono_set_assemblies_path(MONO_VERSION_DATA[(int)MONO_VERSION].path.c_str());
+		Path libDir = Paths::findPath(MONO_LIB_DIR);
+		Path etcDir = getMonoEtcFolder();
+		Path assembliesDir = getFrameworkAssembliesFolder();
+
+		mono_set_dirs(libDir.toString().c_str(), etcDir.toString().c_str());
+		mono_set_assemblies_path(assembliesDir.toString().c_str());
 
 #if BS_DEBUG_MODE
 		mono_set_signal_chaining(true);
@@ -243,18 +248,18 @@ namespace BansheeEngine
 
 	Path MonoManager::getFrameworkAssembliesFolder() const
 	{
-		return MONO_VERSION_DATA[(int)MONO_VERSION].path;
+		return Paths::findPath(MONO_VERSION_DATA[(int)MONO_VERSION].path);
 	}
 
 	Path MonoManager::getMonoEtcFolder() const
 	{
-		return MONO_ETC_DIR;
+		return Paths::findPath(MONO_ETC_DIR);
 	}
 
 	Path MonoManager::getCompilerPath() const
 	{
 		Path compilerPath = FileSystem::getWorkingDirectoryPath();
-		compilerPath.append(MONO_COMPILER_DIR);
+		compilerPath.append(Paths::findPath(MONO_COMPILER_DIR));
 
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 		compilerPath.append("mcs.exe");

+ 4 - 3
ExampleProject/Main/Main.cpp

@@ -133,9 +133,10 @@ int CALLBACK WinMain(
 
 namespace BansheeEngine
 {
-	Path exampleModelPath = RUNTIME_DATA_PATH + "Examples\\Dragon.fbx";
-	Path exampleTexturePath = RUNTIME_DATA_PATH + "Examples\\Dragon.tga";
-	Path exampleShaderPath = RUNTIME_DATA_PATH + "Examples\\Example.bsl";
+	Path dataPath = Application::findPath(RUNTIME_DATA_PATH);
+	Path exampleModelPath = dataPath + "Examples\\Dragon.fbx";
+	Path exampleTexturePath = dataPath + "Examples\\Dragon.tga";
+	Path exampleShaderPath = dataPath + "Examples\\Example.bsl";
 
 	GUIButton* toggleFullscreenButton = nullptr;
 	bool fullscreen = false;

+ 10 - 6
Game/Source/Main.cpp

@@ -45,7 +45,9 @@ using namespace BansheeEngine;
 
 void runApplication()
 {
-	FileDecoder fd(GAME_SETTINGS_PATH);
+	Path gameSettingsPath = Paths::getGameSettingsPath();
+
+	FileDecoder fd(gameSettingsPath);
 	SPtr<GameSettings> gameSettings = std::static_pointer_cast<GameSettings>(fd.decode());
 
 	if (gameSettings == nullptr)
@@ -101,18 +103,20 @@ void runApplication()
 	gameSettings->resolutionWidth = resolutionWidth;
 	gameSettings->resolutionHeight = resolutionHeight;
 
-	FileEncoder fe(GAME_SETTINGS_PATH);
+	FileEncoder fe(gameSettingsPath);
 	fe.encode(gameSettings.get());
 
-	Path resourceManifestPath = GAME_RESOURCES_PATH + GAME_RESOURCE_MANIFEST_NAME;
+	Path resourcesPath = Paths::getGameResourcesPath();
+	Path resourceManifestPath = resourcesPath + GAME_RESOURCE_MANIFEST_NAME;
 
 	ResourceManifestPtr manifest;
 	if (FileSystem::exists(resourceManifestPath))
 	{
-		Path resourcesPath = FileSystem::getWorkingDirectoryPath();
-		resourcesPath.append(APP_ROOT);
+		Path resourceRoot = FileSystem::getWorkingDirectoryPath();
+		resourceRoot.append(resourcesPath);
+		resourceRoot.makeParent(); // Remove /Resources entry, as we expect all resources to be relative to that path
 
-		manifest = ResourceManifest::load(resourceManifestPath, resourcesPath);
+		manifest = ResourceManifest::load(resourceManifestPath, resourceRoot);
 
 		gResources().registerResourceManifest(manifest);
 	}

+ 1 - 3
MBansheeEditor/BuildManager.cs

@@ -339,9 +339,7 @@ namespace BansheeEditor
             // Copy native binaries
             string binaryFolder = GetBuildFolder(BuildFolder.NativeBinaries, activePlatform);
             string srcBin = Path.Combine(srcRoot, binaryFolder);
-            string destBin = Path.Combine(destRoot, binaryFolder);
-
-            Directory.CreateDirectory(destBin);
+            string destBin = destRoot;
 
             string[] nativeBinaries = GetNativeBinaries(activePlatform);
             foreach (var entry in nativeBinaries)

+ 1 - 1
SBansheeEditor/Source/BsScriptBuildManager.cpp

@@ -341,7 +341,7 @@ namespace BansheeEngine
 
 		// Save icon
 		Path iconFolder = FileSystem::getWorkingDirectoryPath();
-		iconFolder.append(BuiltinResources::EngineIconFolder);
+		iconFolder.append(BuiltinResources::getIconFolder());
 
 		Path sourceRoot = BuildManager::instance().getBuildFolder(BuildFolder::SourceRoot, platformInfo->type);
 		iconFolder.makeRelative(sourceRoot);

+ 6 - 2
Scripts/package_editor.py

@@ -30,7 +30,7 @@ outputDataFolder = outputBaseFolder + dataFolder
 outputBinFolder = outputBaseFolder + '\\bin\\'
 outputAssembliesFolder = outputBinFolder + assembliesFolder
 outputMonoFolder = outputBinFolder + monoFolder
-outputLibFolder = outputBinFolder + libFolder
+outputLibFolder = outputBaseFolder
 
 def ignore_data(path, entries):
     if path != inputDataFolder:
@@ -45,4 +45,8 @@ os.makedirs(outputBaseFolder)
 shutil.copytree(inputDataFolder, outputDataFolder, False, ignore_data)
 shutil.copytree(inputAssembliesFolder, outputAssembliesFolder)
 shutil.copytree(inputMonoFolder, outputMonoFolder)
-shutil.copytree(inputLibFolder, outputLibFolder)
+
+for root, dirs, files in os.walk(inputLibFolder):
+    for file in files:
+        filePath = os.path.join(root, file)
+        shutil.copy(filePath, outputLibFolder)