#include #include #include "Engine.h" #include "Controller.h" #include "View.h" #include "Model.h" #include "Physics.h" #include "EntityFactory.h" #include "Game.h" #include #ifdef WIN32 #include #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 paths; paths.push_back("."); paths.push_back("/usr/local/share/fysxasteroids"); paths.push_back("/usr/share/fysxasteroids"); std::vector::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; #ifdef WIN32 HWND hWnd = GetConsoleWindow(); ShowWindow( hWnd, SW_HIDE ); #endif Engine::Engine engine; engine.SetEntityFactory (new asteroids::EntityFactory); engine.SetController (new asteroids::Controller); engine.SetModel (new asteroids::Model); engine.SetPhysics (new asteroids::Physics); engine.SetView (new asteroids::View); SetLogPrintLevel (Engine::LogLevelWarning); // find the path for game data and user data std::string user_path = ""; std::string game_data_path = ""; // use the current path as default boost::filesystem::path cpath = boost::filesystem::initial_path(); user_path = boost::filesystem::path(cpath.string() + user_path).string(); game_data_path = boost::filesystem::path(cpath.string() + game_data_path).string(); #ifndef WIN32 // on linux et al we check more thoroughly at the possible directories user_path = create_user_path(); game_data_path = find_game_data_dir(); #endif // we assume the user path to be local folder std::string log_file_path = user_path; log_file_path += "/game.log"; log_file_path = boost::filesystem::path (log_file_path).string(); cout << "User Data Dir = " << user_path << endl; engine.SetUserDataPath (user_path); Engine::SetLogFilename (log_file_path); 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; exit (-1); } // Load the icon Uint32 colorkey; SDL_Surface *image = NULL; image = SDL_LoadBMP(Engine::GetResourceFullPath("/data/textures/icon.bmp").c_str()); if (!image) Engine::LogWarning("Could not load icon: data/textures/icon.bmp"); else SDL_WM_SetIcon(image,NULL); std::string version_string = "fysxasteroids "; version_string += FYSXASTEROIDS_VERSION; SDL_WM_SetCaption(version_string.c_str(), version_string.c_str()); /// \todo get rid of the world settings in asteroids dynamic_cast(engine.GetPhysics())->SetWorldSize (26, 20); engine.GetPhysics()->SetWorldBounds (vector3d (-13, 0, -10), vector3d (13, 0, 10)); engine.GetPhysics()->EnableWorldWarp(Engine::PhysicsBase::WorldWarpModeX); engine.GetPhysics()->EnableWorldWarp(Engine::PhysicsBase::WorldWarpModeZ); engine.GetView()->SetGridSize (8,8); engine.GetView()->Resize (800, 600); // run the default commands and load the configuration Engine::RunCommand ("exec asteroids.rc"); Engine::RunCommand ("exec config.rc"); Engine::PlayMusic (Engine::GetResourceFullPath("/data/sounds/intro_music.ogg")); Engine::LoadSound(Engine::GetResourceFullPath("/data/sounds/thrust.wav")); Engine::LoadSound(Engine::GetResourceFullPath("/data/sounds/ship_destroyed.wav")); Engine::LoadSound(Engine::GetResourceFullPath("/data/sounds/rock_destroyed.wav")); // load highscore list (either remote or local, depending on settings) asteroids::GetModel()->LoadHighscoreList(); engine.MainLoop (); // save the configuration 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 << "set use_server_highscore " << Engine::GetVariableString("use_server_highscore") << std::endl; config_file << "set use_server_highscore_asked " << Engine::GetVariableString ("use_server_highscore_asked") << std::endl; if (Engine::GetVariableBool("cheat_mode")) config_file << "set cheat_mode " << true << std::endl; config_file.close(); SDL_WM_SetIcon(NULL,NULL); SDL_FreeSurface (image); engine.Destroy (); cout << "Game Quit" << endl; return 0; }