introduced game data dir and user data dir
- the game data dir contains system wide data such as levels, sounds, etc. - user data dir stores higscore, configurations
This commit is contained in:
		
							parent
							
								
									cfedddcae0
								
							
						
					
					
						commit
						d01ab37554
					
				| @ -1,4 +1,4 @@ | ||||
| PROJECT ( Asteroids CXX ) | ||||
| PROJECT ( Asteroids C CXX ) | ||||
| 
 | ||||
| CMAKE_MINIMUM_REQUIRED(VERSION 2.6) | ||||
| 
 | ||||
|  | ||||
| @ -33,7 +33,7 @@ bool Controller::OnReceiveEvent (const Engine::EventBasePtr &event) { | ||||
| } | ||||
| 
 | ||||
| void Controller::ResetPlayerEntity () { | ||||
| 	Engine::HaltSoundLoop("./data/sounds/thrust.wav"); | ||||
| 	Engine::HaltSoundLoop(Engine::GetResourceFullPath("/data/sounds/thrust.wav")); | ||||
| 
 | ||||
| 	Engine::EntityBase *player_entity = GetModel()->GetEntity(GetModel()->GetPlayerEntityId()); | ||||
| 
 | ||||
|  | ||||
| @ -65,7 +65,7 @@ int Model::OnInit (int argc, char* argv[]) { | ||||
| 
 | ||||
| 	mPlayerName = "Player"; | ||||
| 
 | ||||
| 	Engine::PlayMusic ("./data/sounds/intro_music.ogg"); | ||||
| 	Engine::PlayMusic (Engine::GetResourceFullPath("/data/sounds/intro_music.ogg")); | ||||
| 	 | ||||
| 	Engine::RegisterListener (this, EventAccelerateStart); | ||||
| 	Engine::RegisterListener (this, EventAccelerateStop); | ||||
| @ -76,10 +76,10 @@ int Model::OnInit (int argc, char* argv[]) { | ||||
| bool Model::OnReceiveEvent (const Engine::EventBasePtr &event) { | ||||
| 	switch (event->mEventType) { | ||||
| 		case EventAccelerateStart: | ||||
| 			Engine::PlaySoundLoop("./data/sounds/thrust.wav", -1); | ||||
| 			Engine::PlaySoundLoop(Engine::GetResourceFullPath("/data/sounds/thrust.wav"), -1); | ||||
| 			break; | ||||
| 		case EventAccelerateStop: | ||||
| 			Engine::HaltSoundLoop("./data/sounds/thrust.wav"); | ||||
| 			Engine::HaltSoundLoop(Engine::GetResourceFullPath("/data/sounds/thrust.wav")); | ||||
| 			break; | ||||
| 		case EventShipExplode: | ||||
| 			OnShipExplode(); | ||||
| @ -117,19 +117,19 @@ void Model::Process () { | ||||
| } | ||||
| 
 | ||||
| unsigned int Model::InitLevelList () { | ||||
| 	const char* level_dir_name = "./data/levels/"; | ||||
| 	Engine::LogDebug ("Searching for levels in %s", level_dir_name); | ||||
| 	std::string level_dir_name = Engine::GetResourceFullPath("/data/levels/"); | ||||
| 	Engine::LogDebug ("Searching for levels in %s", level_dir_name.c_str()); | ||||
| 
 | ||||
| 	mLevelList.clear(); | ||||
| 
 | ||||
| 	boost::filesystem::path level_dir(level_dir_name); | ||||
| 
 | ||||
| 	if (!boost::filesystem::exists(level_dir)) { | ||||
| 		Engine::LogError ("Could not init level list: %s does not exist!"); | ||||
| 		Engine::LogError ("Could not init level list: \todo %s does not exist!"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (!boost::filesystem::is_directory(level_dir)) { | ||||
| 		Engine::LogError ("Could not init level list: %s is not a directory!"); | ||||
| 		Engine::LogError ("Could not init level list: \todo %s is not a directory!"); | ||||
| 	} | ||||
| 
 | ||||
| 	boost::filesystem::directory_iterator end_iter; | ||||
| @ -151,7 +151,7 @@ unsigned int Model::InitLevelList () { | ||||
| 
 | ||||
| void Model::LoadHighscoreList () { | ||||
| 	Engine::LogDebug ("Loading highscore file"); | ||||
| 	boost::filesystem::path highscore_file("./highscore.dat"); | ||||
| 	boost::filesystem::path highscore_file(Engine::GetUserDirFullPath("/highscore.dat")); | ||||
| 
 | ||||
| 	// if the file does not exist, we create it and write standard values into
 | ||||
| 	// it.
 | ||||
| @ -185,7 +185,7 @@ void Model::LoadHighscoreList () { | ||||
| } | ||||
| 
 | ||||
| void Model::SaveHighscoreList () { | ||||
| 	std::ofstream highscore_file ("./highscore.dat"); | ||||
| 	std::ofstream highscore_file (Engine::GetUserDirFullPath("/highscore.dat").c_str()); | ||||
| 
 | ||||
| 	std::list<HighscoreEntry>::iterator iter = mHighscoreList.begin(); | ||||
| 
 | ||||
| @ -425,7 +425,7 @@ void Model::OnKillEntity (const Engine::EntityBase *entity) { | ||||
| 	GameEntityType entity_type = (GameEntityType) entity->mType; | ||||
| 
 | ||||
| 	if (entity_type == GameEntityTypeAsteroid) { | ||||
| 		Engine::PlaySound("./data/sounds/rock_destroyed.wav"); | ||||
| 		Engine::PlaySound(Engine::GetResourceFullPath("/data/sounds/rock_destroyed.wav")); | ||||
| 
 | ||||
| 		unsigned int i; | ||||
| 		const AsteroidEntity *asteroid = static_cast<const AsteroidEntity*>(entity); | ||||
|  | ||||
| @ -117,7 +117,7 @@ void ShipEntity::Attack () { | ||||
| 	rocket_physics->mVelocity = attack_dir.normalize(); | ||||
| 	rocket_physics->mVelocity *= ShipEntity::VarMaxSpeed.GetFloatValue() + 0.5; | ||||
| 
 | ||||
| 	Engine::PlaySound ("./data/sounds/laser.wav");	 | ||||
| 	Engine::PlaySound (Engine::GetResourceFullPath("/data/sounds/laser.wav"));	 | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  | ||||
| @ -56,16 +56,16 @@ int View::OnInit (int argc, char* argv[]) { | ||||
| 		mBackgroundStars.push_back (star); | ||||
| 	} | ||||
| 
 | ||||
| 	mGUIShipSprite.LoadFromPNG("./data/textures/ship.png"); | ||||
| 	mGUIShipSprite.LoadFromPNG(Engine::GetResourceFullPath("/data/textures/ship.png")); | ||||
| 	mGUIShipSprite.SetScale (0.1); | ||||
| 
 | ||||
| 	mAsteroidSprite.LoadFromPNG ("./data/textures/asteroid.png"); | ||||
| 	mShipSprite.LoadFromPNG ("./data/textures/ship.png"); | ||||
| 	mAsteroidSprite.LoadFromPNG (Engine::GetResourceFullPath("/data/textures/asteroid.png")); | ||||
| 	mShipSprite.LoadFromPNG (Engine::GetResourceFullPath("/data/textures/ship.png")); | ||||
| 
 | ||||
| 	mShipThrustSprite.LoadFromPNG ("./data/textures/ship_thrust.png"); | ||||
| 	mShipThrustSprite.LoadFromPNG (Engine::GetResourceFullPath("/data/textures/ship_thrust.png")); | ||||
| 	mShipThrustSprite.SetAnimation (4, 8); | ||||
| 
 | ||||
| 	mShipPartsSprite.LoadFromPNG ("./data/textures/ship_parts.png"); | ||||
| 	mShipPartsSprite.LoadFromPNG (Engine::GetResourceFullPath("/data/textures/ship_parts.png")); | ||||
| 	mShipPartsSprite.SetSubSpriteCount (10); | ||||
| 
 | ||||
| 	Engine::RegisterListener (this, EventAccelerateStart); | ||||
|  | ||||
| @ -9,12 +9,94 @@ | ||||
| #include "Physics.h" | ||||
| #include "EntityFactory.h" | ||||
| 
 | ||||
| #include <boost/filesystem.hpp> | ||||
| 
 | ||||
| #ifdef WIN32 | ||||
| #include <Windows.h> | ||||
| #endif | ||||
| 
 | ||||
| using namespace std; | ||||
| 
 | ||||
| /* Returns a path where files such as logs and config files can be
 | ||||
|  * written to | ||||
|  */ | ||||
| std::string create_user_path () { | ||||
| 	std::string result_dir = "."; | ||||
| 	std::string test_file_path = result_dir; | ||||
| 
 | ||||
| 	// first we check in $HOME/.fysxasteroids
 | ||||
| 	char* env_home_dir = getenv("HOME"); | ||||
| 	result_dir = env_home_dir; | ||||
| 	result_dir += "/.fysxasteroids"; | ||||
| 
 | ||||
| 	boost::filesystem::path result_dir_path(result_dir); | ||||
| 	if(!boost::filesystem::is_directory (result_dir_path)) { | ||||
| 		if (!boost::filesystem::create_directory(result_dir_path)) { | ||||
| 			cerr << "Warning: could not create user data directory " << result_dir<< endl; | ||||
| 			result_dir = ""; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	test_file_path = result_dir; | ||||
| 	test_file_path += "/game.log"; | ||||
| 	ofstream test_file (test_file_path.c_str(), ios_base::app); | ||||
| 	if (!test_file) { | ||||
| 		test_file.close(); | ||||
| 		cerr << "Warning: user data directory not writable! " << result_dir << endl; | ||||
| 		result_dir = ""; | ||||
| 	} else { | ||||
| 		test_file.close(); | ||||
| 		return result_dir; | ||||
| 	} | ||||
| 
 | ||||
| 	// then we check the local directory
 | ||||
| 	result_dir = "."; | ||||
| 	test_file_path = result_dir; | ||||
| 	test_file_path += "/game.log"; | ||||
| 	test_file.open (test_file_path.c_str(), ios_base::out); | ||||
| 	if (test_file) { | ||||
| 		test_file.close(); | ||||
| 		return result_dir; | ||||
| 	} else { | ||||
| 		cerr << "Warning could not find suitable user data directory" << endl; | ||||
| 		result_dir = ""; | ||||
| 	} | ||||
| 	test_file.close(); | ||||
| 
 | ||||
| 	return result_dir; | ||||
| } | ||||
| 
 | ||||
| std::string find_game_data_dir () { | ||||
| 	std::string result; | ||||
| 
 | ||||
| 	std::vector<std::string> paths; | ||||
| 	paths.push_back("."); | ||||
| 	paths.push_back("/usr/local/share/fysxasteroids"); | ||||
| 	paths.push_back("/usr/share/fysxasteroids"); | ||||
| 
 | ||||
| 	std::vector<std::string>::iterator iter = paths.begin(); | ||||
| 	for (iter; iter != paths.end(); iter++) { | ||||
| 		std::string test_path = *iter; | ||||
| 		 | ||||
| 		if (!boost::filesystem::is_directory(test_path + "/data/fonts")) | ||||
| 			continue; | ||||
| 		if (!boost::filesystem::is_directory(test_path + "/data/levels")) | ||||
| 			continue; | ||||
| 		if (!boost::filesystem::is_directory(test_path + "/data/sounds")) | ||||
| 			continue; | ||||
| 		if (!boost::filesystem::is_directory(test_path + "/data/textures")) | ||||
| 			continue; | ||||
| 
 | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (iter != paths.end()) | ||||
| 		return *iter; | ||||
| 
 | ||||
| 	cerr << "Could not find game data" << endl; | ||||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| int main (int argc, char* argv[]) { | ||||
| 	cout << "Game Start" << endl; | ||||
| 
 | ||||
| @ -32,7 +114,19 @@ int main (int argc, char* argv[]) { | ||||
| 	engine.SetView (new asteroids::View); | ||||
| 
 | ||||
| 	SetLogPrintLevel (Engine::LogLevelMessage); | ||||
| 	Engine::SetLogFilename ("game.log"); | ||||
| 
 | ||||
| 	// we assume the user path to be local folder
 | ||||
| 	std::string user_path = create_user_path(); | ||||
| 	std::string log_file_path = user_path; | ||||
| 	log_file_path += "/game.log"; | ||||
| 
 | ||||
| 	cout << "User Data Dir = " << user_path << endl; | ||||
| 	engine.SetUserDataPath (user_path); | ||||
| 	Engine::SetLogFilename (log_file_path.c_str()); | ||||
| 
 | ||||
| 	std::string game_data_path = find_game_data_dir(); | ||||
| 	engine.SetGameDataPath (game_data_path); | ||||
| 	cout << "Game Data Dir = " << game_data_path << endl; | ||||
| 
 | ||||
| 	if (engine.Init (argc, argv) != 0) { | ||||
| 		cout << "Could not start engine!" << endl; | ||||
| @ -60,7 +154,7 @@ int main (int argc, char* argv[]) { | ||||
| 	engine.MainLoop (); | ||||
| 
 | ||||
| 	// save the configuration
 | ||||
| 	std::ofstream config_file ("config.rc"); | ||||
| 	std::ofstream config_file (engine.GetUserDirFullPath("/config.rc").c_str()); | ||||
| 	config_file << "set effects_volume " << Engine::GetEffectsVolume() << std::endl; | ||||
| 	config_file << "set music_volume " << Engine::GetMusicVolume() << std::endl; | ||||
| 	config_file.close(); | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| #include "Commands.h"  | ||||
| #include <boost/filesystem.hpp> | ||||
| 
 | ||||
| namespace Engine { | ||||
| 
 | ||||
| @ -190,6 +191,40 @@ std::string CommandGetErrorString (){ | ||||
| 	return CommandsInstance->GetErrorString(); | ||||
| } | ||||
| 
 | ||||
| /** \brief Searches for possible candidates at reasonable places
 | ||||
|  * | ||||
|  * In that order: | ||||
|  * 1. current directory | ||||
|  * 2. user data directory | ||||
|  * 3. game data directory | ||||
|  * | ||||
|  * \returns full path to the file, otherwise only the filename (which will | ||||
|  * \returns then cause an error because the file cannot be opened) | ||||
|  */ | ||||
| std::string find_exec_file_full_path (const std::string &exec_file) { | ||||
| 	std::string full_path = exec_file; | ||||
| 
 | ||||
| 	boost::filesystem::path exec_file_path (full_path); | ||||
| 	if(boost::filesystem::is_regular_file(exec_file_path)) { | ||||
| 		return full_path; | ||||
| 	} | ||||
| 
 | ||||
| 	full_path = GetUserDirFullPath(std::string("/") + exec_file); | ||||
| 	exec_file_path = full_path; | ||||
| 	if(boost::filesystem::is_regular_file(exec_file_path)) { | ||||
| 		return full_path; | ||||
| 	} | ||||
| 
 | ||||
| 	full_path = GetResourceFullPath(std::string("/") + exec_file); | ||||
| 	exec_file_path = full_path; | ||||
| 	if(boost::filesystem::is_regular_file(exec_file_path)) { | ||||
| 		return full_path; | ||||
| 	} | ||||
| 
 | ||||
| 	// otherwise just return the normal path which will fail anyway
 | ||||
| 	return exec_file; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Commands of the Command system | ||||
|  */ | ||||
| @ -202,13 +237,16 @@ bool Cmd_Exec (const std::vector<std::string> args) { | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	std::string full_path = find_exec_file_full_path(args[0]); | ||||
| 	LogDebug ("Trying to exec file %s", full_path.c_str()); | ||||
| 
 | ||||
| 	std::ifstream exec_file; | ||||
| 	exec_file.open(args[0].c_str(), std::ios_base::in); | ||||
| 	exec_file.open(full_path.c_str(), std::ios_base::in); | ||||
| 
 | ||||
| 	if (!exec_file) { | ||||
| 		std::ostringstream error_msg; | ||||
| 		error_msg << "exec failed: could not open file '" | ||||
| 			<< args[0] << "'"; | ||||
| 			<< full_path.c_str() << "'"; | ||||
| 		CommandsInstance->SetErrorString(error_msg.str()); | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| @ -363,5 +363,23 @@ ControllerBase* EngineGetController () { | ||||
| 	return EngineInstance->GetController(); | ||||
| } | ||||
| 
 | ||||
| std::string GetResourceFullPath (const std::string &resource) { | ||||
| 	if (EngineInstance == NULL) { | ||||
| 		std::cerr << "Error: Engine Instance not yet initialized!" << std::endl; | ||||
| 		assert (0); | ||||
| 	} | ||||
| 
 | ||||
| 	return EngineInstance->GetResourceFullPath(resource); | ||||
| } | ||||
| 
 | ||||
| std::string GetUserDirFullPath (const std::string &path) { | ||||
| 	if (EngineInstance == NULL) { | ||||
| 		std::cerr << "Error: Engine Instance not yet initialized!" << std::endl; | ||||
| 		assert (0); | ||||
| 	} | ||||
| 
 | ||||
| 	return EngineInstance->GetUserDirFullPath(path); | ||||
| } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -99,6 +99,29 @@ class Engine : public Module { | ||||
| 		void SetStatus (const EngineStatus new_status); | ||||
| 		EngineStatus GetStatus (); | ||||
| 
 | ||||
| 		void SetUserDataPath (const std::string &path) {  | ||||
| 			mUserDataPath = path;  | ||||
| 		}; | ||||
| 		std::string GetUserDataPath () { return mUserDataPath; }; | ||||
| 
 | ||||
| 		void SetGameDataPath (const std::string &path) { | ||||
| 			mGameDataPath = path;  | ||||
| 		}; | ||||
| 		std::string GetGameDataPath () { return mGameDataPath; }; | ||||
| 
 | ||||
| 		/** \brief Returns the path to a resource by prepending the game data path to
 | ||||
| 		 *  \brief it | ||||
| 		 */ | ||||
| 		std::string GetResourceFullPath (const std::string &resource) { | ||||
| 			return mGameDataPath + resource; | ||||
| 		}; | ||||
| 
 | ||||
| 		/** \brief Returns the path to a file by prepending the user data path to it
 | ||||
| 		*/ | ||||
| 		std::string GetUserDirFullPath (const std::string &path) {  | ||||
| 			return mUserDataPath + path;  | ||||
| 		}; | ||||
| 
 | ||||
| 	private: | ||||
| 		// Engine must not be created with the standard constructor! 
 | ||||
| 		// It must be ensured, that the correct EntityFactory is used!
 | ||||
| @ -121,6 +144,9 @@ class Engine : public Module { | ||||
| 		Commands *mCommands; | ||||
| 		Variables *mVariables; | ||||
| 
 | ||||
| 		std::string mUserDataPath; | ||||
| 		std::string mGameDataPath; | ||||
| 
 | ||||
| 		std::string mErrorString; | ||||
| 		EngineStatus mStatus; | ||||
| }; | ||||
| @ -152,6 +178,14 @@ ViewBase* EngineGetView (); | ||||
| /** \brief Global access functions for the Controller */ | ||||
| ControllerBase* EngineGetController (); | ||||
| 
 | ||||
| /** \brief Returns the path to a resource by prepending the game data path to
 | ||||
|  *  \brief it | ||||
|  */ | ||||
| std::string GetResourceFullPath (const std::string &resource); | ||||
| 
 | ||||
| /** \brief Returns the path to a file by prepending the user data path to it
 | ||||
|  */ | ||||
| std::string GetUserDirFullPath (const std::string &path); | ||||
| } | ||||
| 
 | ||||
| /* Include the globally visible declarations of the other modules */ | ||||
|  | ||||
| @ -13,16 +13,16 @@ namespace Engine { | ||||
|  * Code is taken from http://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures on
 | ||||
|  * Sunday, March 14 2010. | ||||
|  */ | ||||
| bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 	LogDebug ("Loading png from %s", filename); | ||||
| bool Sprite::LoadFromPNG (const std::string &filename) { | ||||
| 	LogDebug ("Loading png from %s", filename.c_str()); | ||||
| 
 | ||||
| 	//header for testing if it is a png
 | ||||
| 	png_byte header[8]; | ||||
| 
 | ||||
| 	//open file as binary
 | ||||
| 	FILE *fp = fopen(filename, "rb"); | ||||
| 	FILE *fp = fopen(filename.c_str(), "rb"); | ||||
| 	if (!fp) { | ||||
| 		LogError ("Could not open file: %s", filename); | ||||
| 		LogError ("Could not open file: %s", filename.c_str()); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| @ -32,7 +32,7 @@ bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 	//test if png
 | ||||
| 	int is_png = !png_sig_cmp(header, 0, 8); | ||||
| 	if (!is_png) { | ||||
| 		LogError ("Error opening png file %s: file is not a png file!", filename); | ||||
| 		LogError ("Error opening png file %s: file is not a png file!", filename.c_str()); | ||||
| 		fclose(fp); | ||||
| 		return false; | ||||
| 	} | ||||
| @ -41,7 +41,7 @@ bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 	png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, | ||||
| 			NULL, NULL); | ||||
| 	if (!png_ptr) { | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename); | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename.c_str()); | ||||
| 		fclose(fp); | ||||
| 		return (false); | ||||
| 	} | ||||
| @ -49,7 +49,7 @@ bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 	//create png info struct
 | ||||
| 	png_infop info_ptr = png_create_info_struct(png_ptr); | ||||
| 	if (!info_ptr) { | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename); | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename.c_str()); | ||||
| 		png_destroy_read_struct(&png_ptr, (png_infopp) NULL, (png_infopp) NULL); | ||||
| 		fclose(fp); | ||||
| 		return (false); | ||||
| @ -58,7 +58,7 @@ bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 	//create png info struct
 | ||||
| 	png_infop end_info = png_create_info_struct(png_ptr); | ||||
| 	if (!end_info) { | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename); | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename.c_str()); | ||||
| 		png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); | ||||
| 		fclose(fp); | ||||
| 		return (false); | ||||
| @ -66,7 +66,7 @@ bool Sprite::LoadFromPNG (const char *filename) { | ||||
| 
 | ||||
| 	//png error stuff, not sure libpng man suggests this.
 | ||||
| 	if (setjmp(png_jmpbuf(png_ptr))) { | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename); | ||||
| 		LogError ("Error opening png file %s: unable to read png header", filename.c_str()); | ||||
| 		png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); | ||||
| 		fclose(fp); | ||||
| 		return (false); | ||||
|  | ||||
| @ -17,7 +17,7 @@ class Sprite { | ||||
| 			mSubSpriteCount = 1; | ||||
| 		} | ||||
| 
 | ||||
| 		bool LoadFromPNG (const char *filename); | ||||
| 		bool LoadFromPNG (const std::string &filename); | ||||
| 		void DrawAt (float xpos, float ypos, float zpos); | ||||
| 		void DrawAt2D (float xpos, float ypos); | ||||
| 		unsigned int GetWidth() { return mWidth; }; | ||||
|  | ||||
| @ -275,7 +275,7 @@ bool ViewBase::LoadFont (const std::string &font_spec_string) { | ||||
| 
 | ||||
| 	parse_font_spec_string(font_spec_string, font_name, font_color, &font_size);	 | ||||
| 
 | ||||
| 	std::string font_path ("./data/fonts/"); | ||||
| 	std::string font_path (GetResourceFullPath("/data/fonts/")); | ||||
| 	font_path += font_name; | ||||
| 
 | ||||
| 	LogDebug ("Loading font %s color (%1.2f, %1.2f, %1.2f) size %f from %s", font_name.c_str(), font_color[0], font_color[1], font_color[2], font_size, font_path.c_str()); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user