Browse Source

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 years ago
parent
commit
0025c6b2dd

+ 1 - 0
BansheeCore/Source/BsUtility.cpp

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

+ 28 - 20
BansheeEditor/Include/BsBuiltinEditorResources.h

@@ -186,6 +186,16 @@ namespace BansheeEngine
 		 */
 		 */
 		WString getEmptyCSScriptCode() const;
 		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 ObjectFieldStyleName;
 		static const String ObjectFieldLabelStyleName;
 		static const String ObjectFieldLabelStyleName;
 		static const String ObjectFieldDropBtnStyleName;
 		static const String ObjectFieldDropBtnStyleName;
@@ -196,14 +206,6 @@ namespace BansheeEngine
 		static const String TextureFieldDropStyleName;
 		static const String TextureFieldDropStyleName;
 		static const String TextureFieldClearBtnStyleName;
 		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:
 	private:
 		/**
 		/**
 		 * @brief	Imports all necessary resources and converts them to engine-ready format.
 		 * @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.
 		 * @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.
 		 * @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
 		 * @brief	Loads a shader with the specified filename
 		 */
 		 */
-		static HShader getShader(const WString& name);
+		HShader getShader(const WString& name) const;
 
 
 		HShader mShaderDockOverlay;
 		HShader mShaderDockOverlay;
 		HShader mShaderSceneGrid;
 		HShader mShaderSceneGrid;
@@ -256,17 +258,23 @@ namespace BansheeEngine
 
 
 		ResourceManifestPtr mResourceManifest;
 		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 DefaultFontFilename;
 		static const WString DefaultAAFontFilename;
 		static const WString DefaultAAFontFilename;

+ 0 - 1
BansheeEditor/Include/BsEditorApplication.h

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

+ 12 - 14
BansheeEditor/Source/BsBuildManager.cpp

@@ -91,9 +91,17 @@ namespace BansheeEngine
 
 
 	Path BuildManager::getBuildFolder(BuildFolder folder, PlatformType platform) const
 	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());
 		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)
 		switch (folder)
 		{
 		{
 		case BuildFolder::SourceRoot:
 		case BuildFolder::SourceRoot:
@@ -115,19 +123,9 @@ namespace BansheeEngine
 			return binariesPath.makeRelative(sourceRoot);
 			return binariesPath.makeRelative(sourceRoot);
 		}
 		}
 		case BuildFolder::BansheeAssemblies:
 		case BuildFolder::BansheeAssemblies:
-		{
-			Path dataPath = ASSEMBLY_PATH;
-			dataPath.makeAbsolute(FileSystem::getWorkingDirectoryPath());
-
-			return dataPath.makeRelative(sourceRoot);
-		}
+			return Paths::ASSEMBLY_PATH;
 		case BuildFolder::Data:
 		case BuildFolder::Data:
-		{
-			Path dataPath = ENGINE_DATA_PATH;
-			dataPath.makeAbsolute(FileSystem::getWorkingDirectoryPath());
-
-			return dataPath.makeRelative(sourceRoot);
-		}
+			return Paths::ENGINE_DATA_PATH;
 		}
 		}
 
 
 		return Path::BLANK;
 		return Path::BLANK;
@@ -139,7 +137,7 @@ namespace BansheeEngine
 		{
 		{
 		case PlatformType::Windows:
 		case PlatformType::Windows:
 		{
 		{
-			Path output = RUNTIME_DATA_PATH + "Binaries\\Win64\\Game.exe";
+			Path output = Paths::getRuntimeDataPath() + "Binaries\\Win64\\Game.exe";
 			output.makeAbsolute(FileSystem::getWorkingDirectoryPath());
 			output.makeAbsolute(FileSystem::getWorkingDirectoryPath());
 
 
 			return output;
 			return output;

+ 38 - 23
BansheeEditor/Source/BsBuiltinEditorResources.cpp

@@ -50,6 +50,8 @@
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
+	static const Path EDITOR_DATA_FOLDER = "Editor\\";
+
 	const String BuiltinEditorResources::ObjectFieldStyleName = "GUIObjectField";
 	const String BuiltinEditorResources::ObjectFieldStyleName = "GUIObjectField";
 	const String BuiltinEditorResources::ObjectFieldLabelStyleName = "EditorFieldLabel";
 	const String BuiltinEditorResources::ObjectFieldLabelStyleName = "EditorFieldLabel";
 	const String BuiltinEditorResources::ObjectFieldDropBtnStyleName = "DropButton";
 	const String BuiltinEditorResources::ObjectFieldDropBtnStyleName = "DropButton";
@@ -70,24 +72,10 @@ namespace BansheeEngine
 
 
 	const WString BuiltinEditorResources::GUISkinFile = L"GUISkin";
 	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::FolderIconTex = L"FolderIcon.psd";
 	const WString BuiltinEditorResources::MeshIconTex = L"MeshIcon.psd";
 	const WString BuiltinEditorResources::MeshIconTex = L"MeshIcon.psd";
@@ -302,10 +290,25 @@ namespace BansheeEngine
 
 
 	BuiltinEditorResources::BuiltinEditorResources()
 	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();
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
 		absoluteDataPath.append(BuiltinDataFolder);
 		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"))
 		if (BuiltinResourcesHelper::checkForModifications(BuiltinRawDataFolder, BuiltinDataFolder + L"Timestamp.asset"))
 		{
 		{
 			mResourceManifest = ResourceManifest::create("BuiltinResources");
 			mResourceManifest = ResourceManifest::create("BuiltinResources");
@@ -319,8 +322,9 @@ namespace BansheeEngine
 
 
 			ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 			ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 		}
 		}
-//#endif
+#endif
 
 
+		// Load manifest
 		if (mResourceManifest == nullptr)
 		if (mResourceManifest == nullptr)
 		{
 		{
 			if (FileSystem::exists(ResourceManifestPath))
 			if (FileSystem::exists(ResourceManifestPath))
@@ -332,6 +336,7 @@ namespace BansheeEngine
 			gResources().registerResourceManifest(mResourceManifest);
 			gResources().registerResourceManifest(mResourceManifest);
 		}
 		}
 
 
+		// Load basic resources
 		mShaderDockOverlay = getShader(ShaderDockOverlayFile);
 		mShaderDockOverlay = getShader(ShaderDockOverlayFile);
 		mShaderSceneGrid = getShader(ShaderSceneGridFile);
 		mShaderSceneGrid = getShader(ShaderSceneGridFile);
 		mShaderPicking[(int)CULL_NONE] = getShader(ShaderPickingCullNoneFile);
 		mShaderPicking[(int)CULL_NONE] = getShader(ShaderPickingCullNoneFile);
@@ -1851,7 +1856,7 @@ namespace BansheeEngine
 		return skin;
 		return skin;
 	}
 	}
 
 
-	HSpriteTexture BuiltinEditorResources::getGUITexture(const WString& name)
+	HSpriteTexture BuiltinEditorResources::getGUITexture(const WString& name) const
 	{
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		texturePath.append(EditorSkinFolder);
 		texturePath.append(EditorSkinFolder);
@@ -1860,7 +1865,7 @@ namespace BansheeEngine
 		return gResources().load<SpriteTexture>(texturePath);
 		return gResources().load<SpriteTexture>(texturePath);
 	}
 	}
 
 
-	HSpriteTexture BuiltinEditorResources::getGUIIcon(const WString& name)
+	HSpriteTexture BuiltinEditorResources::getGUIIcon(const WString& name) const
 	{
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		texturePath.append(EditorIconFolder);
 		texturePath.append(EditorIconFolder);
@@ -1869,7 +1874,7 @@ namespace BansheeEngine
 		return gResources().load<SpriteTexture>(texturePath);
 		return gResources().load<SpriteTexture>(texturePath);
 	}
 	}
 
 
-	HShader BuiltinEditorResources::getShader(const WString& name)
+	HShader BuiltinEditorResources::getShader(const WString& name) const
 	{
 	{
 		Path programPath = EditorShaderFolder;
 		Path programPath = EditorShaderFolder;
 		programPath.append(name + L".asset");
 		programPath.append(name + L".asset");
@@ -2227,4 +2232,14 @@ namespace BansheeEngine
 
 
 		return StringUtil::WBLANK;
 		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::WIDGET_LAYOUT_PATH = PROJECT_INTERNAL_DIR + L"Layout.asset";
 	const Path EditorApplication::BUILD_DATA_PATH = PROJECT_INTERNAL_DIR + L"BuildData.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";
 	const Path EditorApplication::PROJECT_SETTINGS_PATH = PROJECT_INTERNAL_DIR + L"Settings.asset";
 
 
 	RENDER_WINDOW_DESC createRenderWindowDesc()
 	RENDER_WINDOW_DESC createRenderWindowDesc()
@@ -59,6 +58,11 @@ namespace BansheeEngine
 		return importers;
 		return importers;
 	}
 	}
 
 
+	Path getEditorSettingsPath()
+	{
+		return Paths::getRuntimeDataPath() + L"Settings.asset";
+	}
+
 	EditorApplication::EditorApplication(EditorRenderAPI renderAPIPlugin)
 	EditorApplication::EditorApplication(EditorRenderAPI renderAPIPlugin)
 		:Application(createRenderWindowDesc(), toEngineRenderAPI(renderAPIPlugin), RendererPlugin::Default, getImporters()),
 		:Application(createRenderWindowDesc(), toEngineRenderAPI(renderAPIPlugin), RendererPlugin::Default, getImporters()),
 		mActiveRAPIPlugin(toEngineRenderAPI(renderAPIPlugin)), mSBansheeEditorPlugin(nullptr), mIsProjectLoaded(false)
 		mActiveRAPIPlugin(toEngineRenderAPI(renderAPIPlugin)), mSBansheeEditorPlugin(nullptr), mIsProjectLoaded(false)
@@ -279,7 +283,7 @@ namespace BansheeEngine
 			FileSystem::createDir(internalResourcesDir);
 			FileSystem::createDir(internalResourcesDir);
 
 
 		Path defaultLayoutPath = FileSystem::getWorkingDirectoryPath();
 		Path defaultLayoutPath = FileSystem::getWorkingDirectoryPath();
-		defaultLayoutPath.append(BuiltinEditorResources::DefaultWidgetLayoutPath);
+		defaultLayoutPath.append(BuiltinEditorResources::getDefaultWidgetLayoutPath());
 
 
 		if (FileSystem::exists(defaultLayoutPath))
 		if (FileSystem::exists(defaultLayoutPath))
 		{
 		{
@@ -325,7 +329,7 @@ namespace BansheeEngine
 	void EditorApplication::loadEditorSettings()
 	void EditorApplication::loadEditorSettings()
 	{
 	{
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(EDITOR_SETTINGS_PATH);
+		absoluteDataPath.append(getEditorSettingsPath());
 
 
 		if (FileSystem::exists(absoluteDataPath))
 		if (FileSystem::exists(absoluteDataPath))
 		{
 		{
@@ -343,7 +347,7 @@ namespace BansheeEngine
 			return;
 			return;
 
 
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(EDITOR_SETTINGS_PATH);
+		absoluteDataPath.append(getEditorSettingsPath());
 
 
 		FileEncoder fs(absoluteDataPath);
 		FileEncoder fs(absoluteDataPath);
 		fs.encode(mEditorSettings.get());
 		fs.encode(mEditorSettings.get());

+ 2 - 2
BansheeEditor/Source/BsShaderIncludeHandler.cpp

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

+ 2 - 0
BansheeEngine/BansheeEngine.vcxproj

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

+ 6 - 0
BansheeEngine/BansheeEngine.vcxproj.filters

@@ -362,6 +362,9 @@
     <ClInclude Include="Include\BsGameSettingsRTTI.h">
     <ClInclude Include="Include\BsGameSettingsRTTI.h">
       <Filter>Header Files\RTTI</Filter>
       <Filter>Header Files\RTTI</Filter>
     </ClInclude>
     </ClInclude>
+    <ClInclude Include="Include\BsPaths.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
   </ItemGroup>
   </ItemGroup>
   <ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsGUIElement.cpp">
     <ClCompile Include="Source\BsGUIElement.cpp">
@@ -619,5 +622,8 @@
     <ClCompile Include="Source\BsGameSettings.cpp">
     <ClCompile Include="Source\BsGameSettings.cpp">
       <Filter>Source Files</Filter>
       <Filter>Source Files</Filter>
     </ClCompile>
     </ClCompile>
+    <ClCompile Include="Source\BsPaths.cpp">
+      <Filter>Source Files</Filter>
+    </ClCompile>
   </ItemGroup>
   </ItemGroup>
 </Project>
 </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.
 		 * @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.
 		 * @brief	Returns image data the Banshee Engine splash screen.
 		 */
 		 */
 		static PixelDataPtr getSplashScreen();
 		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;
 		static const WString IconTextureName;
 	private:
 	private:
 		/**
 		/**
@@ -158,12 +161,12 @@ namespace BansheeEngine
 		/**
 		/**
 		 * @brief	Loads a GUI skin texture with the specified filename.
 		 * @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.
 		 * @brief	Loads a cursor texture with the specified filename.
 		 */
 		 */
-		static HTexture getCursorTexture(const WString& name);
+		HTexture getCursorTexture(const WString& name);
 
 
 		HGUISkin mSkin;
 		HGUISkin mSkin;
 
 
@@ -188,21 +191,29 @@ namespace BansheeEngine
 
 
 		ResourceManifestPtr mResourceManifest;
 		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 WString DefaultFontFilename;
 		static const UINT32 DefaultFontSize;
 		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 "BsGameObject.h"
 #include "BsEnums.h"
 #include "BsEnums.h"
 #include "BsHEString.h"
 #include "BsHEString.h"
+#include "BsPaths.h"
 
 
 namespace BansheeEngine
 namespace BansheeEngine
 {
 {
@@ -130,18 +131,6 @@ namespace BansheeEngine
 	typedef ResourceHandle<ScriptCode> HScriptCode;
 	typedef ResourceHandle<ScriptCode> HScriptCode;
 	typedef ResourceHandle<GUISkin> HGUISkin;
 	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.
 	 * @brief	RTTI types.
 	 */
 	 */

+ 2 - 2
BansheeEngine/Source/BsApplication.cpp

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

+ 61 - 47
BansheeEngine/Source/BsBuiltinResources.cpp

@@ -45,29 +45,12 @@ namespace BansheeEngine
 
 
 	const WString BuiltinResources::GUISkinFile = L"GUISkin";
 	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                      		*/
 	/* 								GUI TEXTURES                      		*/
@@ -206,8 +189,27 @@ namespace BansheeEngine
 
 
 	BuiltinResources::BuiltinResources()
 	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();
 		Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-		absoluteDataPath.append(BuiltinDataFolder);
+		absoluteDataPath.append(mBuiltinDataFolder);
 
 
 		if (FileSystem::exists(ResourceManifestPath))
 		if (FileSystem::exists(ResourceManifestPath))
 			mResourceManifest = ResourceManifest::load(ResourceManifestPath, absoluteDataPath);
 			mResourceManifest = ResourceManifest::load(ResourceManifestPath, absoluteDataPath);
@@ -217,22 +219,24 @@ namespace BansheeEngine
 
 
 		gResources().registerResourceManifest(mResourceManifest);
 		gResources().registerResourceManifest(mResourceManifest);
 
 
+		// Update from raw assets if needed
 #if BS_DEBUG_MODE
 #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();
 				preprocess();
-				BuiltinResourcesHelper::writeTimestamp(BuiltinDataFolder + L"Timestamp.asset");
+				BuiltinResourcesHelper::writeTimestamp(mBuiltinDataFolder + L"Timestamp.asset");
 
 
 				Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
 				Path absoluteDataPath = FileSystem::getWorkingDirectoryPath();
-				absoluteDataPath.append(BuiltinDataFolder);
+				absoluteDataPath.append(mBuiltinDataFolder);
 
 
 				ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 				ResourceManifest::save(mResourceManifest, ResourceManifestPath, absoluteDataPath);
 			}
 			}
 		}
 		}
 #endif
 #endif
 		
 		
+		// Load basic resources
 		mShaderSpriteText = getShader(ShaderSpriteTextFile);
 		mShaderSpriteText = getShader(ShaderSpriteTextFile);
 		mShaderSpriteImage = getShader(ShaderSpriteImageAlphaFile);
 		mShaderSpriteImage = getShader(ShaderSpriteImageAlphaFile);
 		mShaderSpriteNonAlphaImage = getShader(ShaderSpriteImageNoAlphaFile);
 		mShaderSpriteNonAlphaImage = getShader(ShaderSpriteImageNoAlphaFile);
@@ -240,7 +244,7 @@ namespace BansheeEngine
 
 
 		mWhiteSpriteTexture = getSkinTexture(WhiteTex);
 		mWhiteSpriteTexture = getSkinTexture(WhiteTex);
 
 
-		mSkin = gResources().load<GUISkin>(BuiltinDataFolder + (GUISkinFile + L".asset"));
+		mSkin = gResources().load<GUISkin>(mBuiltinDataFolder + (GUISkinFile + L".asset"));
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								CURSOR		                     		*/
 		/* 								CURSOR		                     		*/
@@ -292,7 +296,7 @@ namespace BansheeEngine
 		/************************************************************************/
 		/************************************************************************/
 
 
 		Path iconPath = FileSystem::getWorkingDirectoryPath();
 		Path iconPath = FileSystem::getWorkingDirectoryPath();
-		iconPath.append(EngineIconFolder);
+		iconPath.append(mEngineIconFolder);
 		iconPath.append(IconTextureName + L".asset");
 		iconPath.append(IconTextureName + L".asset");
 
 
 		HTexture iconTex = gResources().load<Texture>(iconPath);
 		HTexture iconTex = gResources().load<Texture>(iconPath);
@@ -305,20 +309,20 @@ namespace BansheeEngine
 
 
 	void BuiltinResources::preprocess()
 	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
 		// Import font
-		BuiltinResourcesHelper::importFont(BuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, BuiltinDataFolder,
+		BuiltinResourcesHelper::importFont(mBuiltinRawDataFolder + DefaultFontFilename, DefaultFontFilename, mBuiltinDataFolder,
 			{ DefaultFontSize }, false, mResourceManifest);
 			{ DefaultFontSize }, false, mResourceManifest);
 
 
 		// Import splash screen
 		// 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);
 			auto textureIO = gImporter().createImportOptions<TextureImportOptions>(inputPath);
 			textureIO->setCPUReadable(true);
 			textureIO->setCPUReadable(true);
@@ -332,12 +336,12 @@ namespace BansheeEngine
 		}
 		}
 
 
 		// Generate & save GUI sprite textures
 		// Generate & save GUI sprite textures
-		BuiltinResourcesHelper::generateSpriteTextures(EngineSkinFolder, mResourceManifest);
+		BuiltinResourcesHelper::generateSpriteTextures(mEngineSkinFolder, mResourceManifest);
 
 
 		// Generate & save GUI skin
 		// Generate & save GUI skin
 		{
 		{
 			HGUISkin skin = generateGUISkin();
 			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);
 			Resources::instance().save(skin, outputPath, true);
 			mResourceManifest->registerResource(skin.getUUID(), outputPath);
 			mResourceManifest->registerResource(skin.getUUID(), outputPath);
 		}
 		}
@@ -351,7 +355,7 @@ namespace BansheeEngine
 	HGUISkin BuiltinResources::generateGUISkin()
 	HGUISkin BuiltinResources::generateGUISkin()
 	{
 	{
 		Path fontPath = FileSystem::getWorkingDirectoryPath();
 		Path fontPath = FileSystem::getWorkingDirectoryPath();
-		fontPath.append(BuiltinDataFolder);
+		fontPath.append(mBuiltinDataFolder);
 		fontPath.append(DefaultFontFilename + L".asset");
 		fontPath.append(DefaultFontFilename + L".asset");
 
 
 		HFont font = gResources().load<Font>(fontPath);
 		HFont font = gResources().load<Font>(fontPath);
@@ -808,7 +812,7 @@ namespace BansheeEngine
 		HMesh discMesh = Mesh::create(discMeshData);
 		HMesh discMesh = Mesh::create(discMeshData);
 
 
 		// Save all meshes
 		// Save all meshes
-		Path outputDir = FileSystem::getWorkingDirectoryPath() + EngineMeshFolder;
+		Path outputDir = FileSystem::getWorkingDirectoryPath() + mEngineMeshFolder;
 
 
 		Path meshPath = outputDir + MeshBoxFile;
 		Path meshPath = outputDir + MeshBoxFile;
 		Resources::instance().save(boxMesh, meshPath, true);
 		Resources::instance().save(boxMesh, meshPath, true);
@@ -834,7 +838,7 @@ namespace BansheeEngine
 	HSpriteTexture BuiltinResources::getSkinTexture(const WString& name)
 	HSpriteTexture BuiltinResources::getSkinTexture(const WString& name)
 	{
 	{
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
 		Path texturePath = FileSystem::getWorkingDirectoryPath();
-		texturePath.append(EngineSkinFolder);
+		texturePath.append(mEngineSkinFolder);
 		texturePath.append(L"sprite_" + name + L".asset");
 		texturePath.append(L"sprite_" + name + L".asset");
 
 
 		return gResources().load<SpriteTexture>(texturePath);
 		return gResources().load<SpriteTexture>(texturePath);
@@ -842,7 +846,7 @@ namespace BansheeEngine
 
 
 	HShader BuiltinResources::getShader(const Path& path)
 	HShader BuiltinResources::getShader(const Path& path)
 	{
 	{
-		Path programPath = EngineShaderFolder;
+		Path programPath = mEngineShaderFolder;
 		programPath.append(path);
 		programPath.append(path);
 		programPath.setExtension(programPath.getExtension() + ".asset");
 		programPath.setExtension(programPath.getExtension() + ".asset");
 
 
@@ -852,7 +856,7 @@ namespace BansheeEngine
 	HTexture BuiltinResources::getCursorTexture(const WString& name)
 	HTexture BuiltinResources::getCursorTexture(const WString& name)
 	{
 	{
 		Path cursorPath = FileSystem::getWorkingDirectoryPath();
 		Path cursorPath = FileSystem::getWorkingDirectoryPath();
-		cursorPath.append(EngineCursorFolder);
+		cursorPath.append(mEngineCursorFolder);
 		cursorPath.append(name + L".asset");
 		cursorPath.append(name + L".asset");
 
 
 		return gResources().load<Texture>(cursorPath);
 		return gResources().load<Texture>(cursorPath);
@@ -925,16 +929,26 @@ namespace BansheeEngine
 
 
 	PixelDataPtr BuiltinResources::getSplashScreen()
 	PixelDataPtr BuiltinResources::getSplashScreen()
 	{
 	{
-		Path splashScreenPath = BuiltinDataFolder + (WString(SplashScreenName) + L".asset");
+		Path splashScreenPath = Paths::getEngineDataPath() + (WString(SplashScreenName) + L".asset");
 		FileDecoder fd(splashScreenPath);
 		FileDecoder fd(splashScreenPath);
 
 
 		return std::static_pointer_cast<PixelData>(fd.decode());
 		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
 	HMesh BuiltinResources::getMesh(BuiltinMesh mesh) const
 	{
 	{
 		Path meshPath = FileSystem::getWorkingDirectoryPath();
 		Path meshPath = FileSystem::getWorkingDirectoryPath();
-		meshPath.append(EngineMeshFolder);
+		meshPath.append(mEngineMeshFolder);
 
 
 		switch (mesh)
 		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 "BsMonoClass.h"
 #include "BsMonoUtil.h"
 #include "BsMonoUtil.h"
 #include "BsFileSystem.h"
 #include "BsFileSystem.h"
+#include "BsApplication.h"
 
 
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/assembly.h>
 #include <mono/metadata/mono-config.h>
 #include <mono/metadata/mono-config.h>
@@ -13,9 +14,9 @@
 
 
 namespace BansheeEngine
 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;
 	const MonoVersion MONO_VERSION = MonoVersion::v4_5;
 	
 	
 	struct MonoVersionData
 	struct MonoVersionData
@@ -33,8 +34,12 @@ namespace BansheeEngine
 	MonoManager::MonoManager()
 	MonoManager::MonoManager()
 		:mRootDomain(nullptr), mScriptDomain(nullptr), mIsCoreLoaded(false)
 		: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
 #if BS_DEBUG_MODE
 		mono_set_signal_chaining(true);
 		mono_set_signal_chaining(true);
@@ -243,18 +248,18 @@ namespace BansheeEngine
 
 
 	Path MonoManager::getFrameworkAssembliesFolder() const
 	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
 	Path MonoManager::getMonoEtcFolder() const
 	{
 	{
-		return MONO_ETC_DIR;
+		return Paths::findPath(MONO_ETC_DIR);
 	}
 	}
 
 
 	Path MonoManager::getCompilerPath() const
 	Path MonoManager::getCompilerPath() const
 	{
 	{
 		Path compilerPath = FileSystem::getWorkingDirectoryPath();
 		Path compilerPath = FileSystem::getWorkingDirectoryPath();
-		compilerPath.append(MONO_COMPILER_DIR);
+		compilerPath.append(Paths::findPath(MONO_COMPILER_DIR));
 
 
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 #if BS_PLATFORM == BS_PLATFORM_WIN32
 		compilerPath.append("mcs.exe");
 		compilerPath.append("mcs.exe");

+ 4 - 3
ExampleProject/Main/Main.cpp

@@ -133,9 +133,10 @@ int CALLBACK WinMain(
 
 
 namespace BansheeEngine
 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;
 	GUIButton* toggleFullscreenButton = nullptr;
 	bool fullscreen = false;
 	bool fullscreen = false;

+ 10 - 6
Game/Source/Main.cpp

@@ -45,7 +45,9 @@ using namespace BansheeEngine;
 
 
 void runApplication()
 void runApplication()
 {
 {
-	FileDecoder fd(GAME_SETTINGS_PATH);
+	Path gameSettingsPath = Paths::getGameSettingsPath();
+
+	FileDecoder fd(gameSettingsPath);
 	SPtr<GameSettings> gameSettings = std::static_pointer_cast<GameSettings>(fd.decode());
 	SPtr<GameSettings> gameSettings = std::static_pointer_cast<GameSettings>(fd.decode());
 
 
 	if (gameSettings == nullptr)
 	if (gameSettings == nullptr)
@@ -101,18 +103,20 @@ void runApplication()
 	gameSettings->resolutionWidth = resolutionWidth;
 	gameSettings->resolutionWidth = resolutionWidth;
 	gameSettings->resolutionHeight = resolutionHeight;
 	gameSettings->resolutionHeight = resolutionHeight;
 
 
-	FileEncoder fe(GAME_SETTINGS_PATH);
+	FileEncoder fe(gameSettingsPath);
 	fe.encode(gameSettings.get());
 	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;
 	ResourceManifestPtr manifest;
 	if (FileSystem::exists(resourceManifestPath))
 	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);
 		gResources().registerResourceManifest(manifest);
 	}
 	}

+ 1 - 3
MBansheeEditor/BuildManager.cs

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

+ 1 - 1
SBansheeEditor/Source/BsScriptBuildManager.cpp

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

+ 6 - 2
Scripts/package_editor.py

@@ -30,7 +30,7 @@ outputDataFolder = outputBaseFolder + dataFolder
 outputBinFolder = outputBaseFolder + '\\bin\\'
 outputBinFolder = outputBaseFolder + '\\bin\\'
 outputAssembliesFolder = outputBinFolder + assembliesFolder
 outputAssembliesFolder = outputBinFolder + assembliesFolder
 outputMonoFolder = outputBinFolder + monoFolder
 outputMonoFolder = outputBinFolder + monoFolder
-outputLibFolder = outputBinFolder + libFolder
+outputLibFolder = outputBaseFolder
 
 
 def ignore_data(path, entries):
 def ignore_data(path, entries):
     if path != inputDataFolder:
     if path != inputDataFolder:
@@ -45,4 +45,8 @@ os.makedirs(outputBaseFolder)
 shutil.copytree(inputDataFolder, outputDataFolder, False, ignore_data)
 shutil.copytree(inputDataFolder, outputDataFolder, False, ignore_data)
 shutil.copytree(inputAssembliesFolder, outputAssembliesFolder)
 shutil.copytree(inputAssembliesFolder, outputAssembliesFolder)
 shutil.copytree(inputMonoFolder, outputMonoFolder)
 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)