diff --git a/CMakeLists.txt b/CMakeLists.txt index 46ec3ba..fb4a367 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,8 +32,15 @@ endif() # Recherche des librairies set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}" ${CMAKE_MODULE_PATH}) add_executable(ptf ${SOURCES}) + find_package(SFML 2 REQUIRED system window graphics network audio) +find_package(Boost 1.60.0 COMPONENTS system filesystem) + +include_directories(${SFML_INCLUDE_DIRS}) +include_directories(${Boost_INCLUDE_DIRS}) + target_link_libraries(ptf ${SFML_LIBRARIES}) +target_link_libraries(ptf ${Boost_LIBRARIES}) # Installation de l'exécutable install(TARGETS ptf DESTINATION bin) diff --git a/include/manager.hpp b/include/manager.hpp index cd0a4c7..8ed6426 100644 --- a/include/manager.hpp +++ b/include/manager.hpp @@ -12,13 +12,12 @@ class Manager { private: sf::RenderWindow window; + ResourceManager resource_manager; + sf::Clock clock; sf::View default_view; sf::String title; - ResourceManager resource_manager; - std::vector events; - std::shared_ptr state; std::shared_ptr next_state; diff --git a/include/resource_manager.hpp b/include/resource_manager.hpp index f8c85fb..e20d822 100644 --- a/include/resource_manager.hpp +++ b/include/resource_manager.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -16,29 +17,34 @@ */ class ResourceManager { private: - std::string resources_dir; + bool preloaded; + boost::filesystem::path textures_path; std::unordered_map> textures; + boost::filesystem::path fonts_path; std::unordered_map> fonts; + boost::filesystem::path levels_path; + + boost::filesystem::path musics_path; float music_volume; sf::Music music; public: ResourceManager(); - ~ResourceManager(); /** - * Récupère une image. Réutilise l'image déjà chargée - * si elle l'a déjà été, sinon, tente de la charger - * depuis son emplacement + * Précharge toutes les ressources préchargeables + */ + void preload(); + + /** + * Récupère une texture préchargée */ sf::Texture& getTexture(std::string name); /** - * Récupère la police demandée. Réutilise une police - * déjà chargée si elle a déjà été demandée, sinon, la - * charge depuis son emplacement + * Récupère une police préchargée */ sf::Font& getFont(std::string name); diff --git a/src/editor.cpp b/src/editor.cpp index fef4ba7..f4ad253 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -52,6 +52,9 @@ Editor::~Editor() {} void Editor::begin() { Level::begin(); + getResourceManager().stopMusic(); + // TODO: on doit arrêter la musique car celle du + // niveau est chargée par dessous dans level.. C'est sale getResourceManager().playMusic("editor.ogg"); getWindow().setFramerateLimit(Manager::FPS); } diff --git a/src/manager.cpp b/src/manager.cpp index 12e3947..830fcb8 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1,13 +1,21 @@ +#include #include "manager.hpp" const unsigned int Manager::FPS = 60; const sf::Time Manager::FRAME_TIME = sf::seconds(1.f / Manager::FPS); -Manager::Manager() : window( - sf::VideoMode(704, 480), "Skizzle", sf::Style::Default, - sf::ContextSettings(0, 0, 2) -), default_view(window.getDefaultView()), title(sf::String(L"")), -state(NULL), next_state(NULL), running(false) {} +Manager::Manager() : default_view(window.getDefaultView()), +title(sf::String(L"")), state(NULL), next_state(NULL), running(false) { + // préchargement des textures + resource_manager.preload(); + + // création de la fenêtre (après avoir préchargé les ressources, + // on évite ainsi tout lag pendant le traitement des événements) + window.create( + sf::VideoMode(704, 480), "Skizzle", sf::Style::Default, + sf::ContextSettings(0, 0, 2) + ); +} void Manager::start() { running = true; diff --git a/src/resource_manager.cpp b/src/resource_manager.cpp index 5df6c9b..10600d9 100644 --- a/src/resource_manager.cpp +++ b/src/resource_manager.cpp @@ -1,86 +1,104 @@ #include "resource_manager.hpp" -#include "whereami.h" +#include #include -// définition du séparateur de fichiers en fonction -// du type de système -#ifdef _WIN32 -const std::string SEP = "\\"; -#else -const std::string SEP = "/"; -#endif - -ResourceManager::ResourceManager() : music_volume(5) { - // on récupère le chemin actuel de l'exécutable pour pouvoir accéder - // au dossier des ressources qui est situé dans le même dossier - int length = wai_getExecutablePath(NULL, 0, NULL), dirname_length; - std::unique_ptr buffer = std::unique_ptr(new char[length + 1]); - wai_getExecutablePath(buffer.get(), length, &dirname_length); - - if (length == 0) { - throw std::runtime_error("Impossible de déterminer le chemin actuel"); - } - - buffer.get()[length] = '\0'; - std::string base_dir = std::string(buffer.get()).substr(0, dirname_length); - resources_dir = base_dir + SEP + "res" + SEP; +using dir_iter = boost::filesystem::directory_iterator; +using fs_path = boost::filesystem::path; +ResourceManager::ResourceManager() : preloaded(false), music_volume(20) { // initialisation de la musique en bouclage et au volume par défaut music.setLoop(true); music.setVolume(music_volume); } -ResourceManager::~ResourceManager() { - textures.clear(); - fonts.clear(); +void ResourceManager::preload() { + if (preloaded) { + return; + } + + fs_path current = boost::filesystem::current_path(); + dir_iter end; + + // on garde une référence aux chemins des différentes ressources + textures_path = current / "res/textures"; + fonts_path = current / "res/fonts"; + levels_path = current / "res/levels"; + musics_path = current / "res/musics"; + + // préchargement de toutes les textures + for (dir_iter it(textures_path); it != end; ++it) { + if (boost::filesystem::is_regular_file(it->path())) { + std::string full_path = boost::filesystem::canonical(it->path()).string(); + std::string name = it->path().filename().string(); + + auto texture = std::unique_ptr(new sf::Texture); + std::cout << "Chargement de la texture " << name << "... "; + + if (!texture->loadFromFile(full_path)) { + std::cerr << "ERREUR!" << std::endl; + } else { + std::cout << "OK!" << std::endl; + } + + textures[name] = std::move(texture); + } + } + + // préchargement de toutes les polices + for (dir_iter it(fonts_path); it != end; ++it) { + if (boost::filesystem::is_regular_file(it->path())) { + std::string full_path = boost::filesystem::canonical(it->path()).string(); + std::string name = it->path().filename().string(); + + auto font = std::unique_ptr(new sf::Font); + std::cout << "Chargement de la police " << name << "... "; + + if (!font->loadFromFile(full_path)) { + std::cerr << "ERREUR!" << std::endl; + } else { + std::cout << "OK!" << std::endl; + } + + fonts[name] = std::move(font); + } + } + + preloaded = true; } sf::Texture& ResourceManager::getTexture(std::string name) { - // si la texture est déjà chargée, on l'utilise directement - if (textures.count(name) > 0) { - return *textures[name]; - } - - auto texture = std::unique_ptr(new sf::Texture); - - // tente de charger la texture dans le chemin "res/textures/name.png" - if (!texture->loadFromFile(resources_dir + SEP + "textures" + SEP + name)) { + if (textures.count(name) == 0) { throw std::runtime_error( - "Impossible de charger l'image \"" + name + "\"" + "Impossible de charger la texture inexistante : " + name ); } - textures[name] = std::move(texture); return *textures[name]; } sf::Font& ResourceManager::getFont(std::string name) { - // si la police est déjà chargée, on l'utilise directement - if (fonts.count(name) > 0) { - return *fonts[name]; - } - - auto font = std::unique_ptr(new sf::Font); - - // tente de charger la police depuis le dossier "res/fonts" - if (!font->loadFromFile(resources_dir + SEP + "fonts" + SEP + name)) { + if (fonts.count(name) == 0) { throw std::runtime_error( - "Impossible de charger la police \"" + name + "\"" + "Impossible de charger la police inexistante : " + name ); } - fonts[name] = std::move(font); return *fonts[name]; } std::string ResourceManager::getLevelPath(std::string name) { - return resources_dir + SEP + "levels" + SEP + name; + return boost::filesystem::canonical(levels_path / name).string(); } void ResourceManager::playMusic(std::string name) { // tente de charger la musique depuis le dossier "res/musics" - if (!music.openFromFile(resources_dir + SEP + "musics" + SEP + name)) { - throw std::runtime_error("Impossible de charger la musique : " + name); + std::string full_path = boost::filesystem::canonical(musics_path / name).string(); + std::cout << "Lecture de la musique " << name << "... "; + + if (!music.openFromFile(full_path)) { + std::cerr << "ERREUR!" << std::endl; + } else { + std::cout << "OK!" << std::endl; } music.play();