├── assets ├── test.png ├── FiraMono-Regular.otf └── LICENSE ├── .gitignore ├── src ├── main.cpp ├── state.hpp ├── asset_manager.hpp ├── pause_state.hpp ├── asset_manager.cpp ├── game_state.hpp ├── state_machine.hpp ├── game.hpp ├── state_machine.cpp ├── pause_state.cpp ├── game.cpp └── game_state.cpp ├── CMakeLists.txt ├── LICENSE ├── README.md └── cmake └── FindSFML.cmake /assets/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiswa/SFML_Starter/HEAD/assets/test.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | SfmlStarter 2 | CMakeFiles 3 | CMakeCache.txt 4 | cmake_install.cmake 5 | Makefile 6 | -------------------------------------------------------------------------------- /assets/FiraMono-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kiswa/SFML_Starter/HEAD/assets/FiraMono-Regular.otf -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "game.hpp" 2 | 3 | int main(int argc, char** argv) { 4 | kg::Game(800, 600, "SFML Starter"); 5 | } 6 | -------------------------------------------------------------------------------- /src/state.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STATE_HPP 2 | #define STATE_HPP 3 | 4 | namespace kg { 5 | class State { 6 | public: 7 | virtual void init() = 0; 8 | 9 | virtual void handleInput() = 0; 10 | virtual void update(float dt) = 0; 11 | virtual void render(float dt) = 0; 12 | 13 | virtual void pause() { } 14 | virtual void resume() { } 15 | }; 16 | } 17 | 18 | #endif // STATE_HPP 19 | -------------------------------------------------------------------------------- /src/asset_manager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSET_MANAGER_HPP 2 | #define ASSET_MANAGER_HPP 3 | 4 | #include 5 | 6 | namespace sf { 7 | class Texture; 8 | class Font; 9 | } 10 | 11 | namespace kg { 12 | class AssetManager { 13 | public: 14 | AssetManager() { } 15 | ~AssetManager() { } 16 | 17 | void loadTexture(std::string name, std::string fileName); 18 | sf::Texture& getTexture(std::string name); 19 | 20 | void loadFont(std::string name, std::string fileName); 21 | sf::Font& getFont(std::string name); 22 | 23 | private: 24 | std::map _textures; 25 | std::map _fonts; 26 | }; 27 | } 28 | 29 | #endif // ASSET_MANAGER_HPP 30 | -------------------------------------------------------------------------------- /src/pause_state.hpp: -------------------------------------------------------------------------------- 1 | #ifndef PAUSE_STATE_HPP 2 | #define PAUSE_STATE_HPP 3 | 4 | #include 5 | #include "state.hpp" 6 | #include "game.hpp" 7 | 8 | namespace kg { 9 | class PauseState : public State { 10 | public: 11 | PauseState(GameDataRef data); 12 | 13 | void init(); 14 | 15 | // Again, no pause() or resume() methods. 16 | // This state only exists to demonstrate a state transition. 17 | 18 | void handleInput(); 19 | void update(float dt) { } // Nothing to do here. 20 | void render(float dt); 21 | 22 | private: 23 | GameDataRef _data; 24 | 25 | sf::Text _text; 26 | }; 27 | } 28 | 29 | #endif // PAUSE_STATE_HPP 30 | -------------------------------------------------------------------------------- /src/asset_manager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "asset_manager.hpp" 3 | 4 | namespace kg { 5 | void AssetManager::loadTexture(std::string name, std::string fileName) { 6 | sf::Texture tex; 7 | if (tex.loadFromFile(fileName)) { 8 | _textures[name] = tex; 9 | } 10 | } 11 | 12 | sf::Texture& AssetManager::getTexture(std::string name) { 13 | return _textures.at(name); 14 | } 15 | 16 | void AssetManager::loadFont(std::string name, std::string fileName) { 17 | sf::Font font; 18 | if (font.loadFromFile(fileName)) { 19 | _fonts[name] = font; 20 | } 21 | } 22 | 23 | sf::Font& AssetManager::getFont(std::string name) { 24 | return _fonts.at(name); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/game_state.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GAME_STATE_HPP 2 | #define GAME_STATE_HPP 3 | 4 | #include 5 | #include "state.hpp" 6 | #include "game.hpp" 7 | 8 | namespace kg { 9 | class GameState : public State { 10 | public: 11 | GameState(GameDataRef data); 12 | 13 | void init(); 14 | 15 | // No pause() or resume() methods here as this 16 | // is a very simple example of a game state. 17 | 18 | void handleInput(); 19 | void update(float dt); 20 | void render(float dt); 21 | 22 | private: 23 | GameDataRef _data; 24 | 25 | sf::Sprite _sprite; 26 | sf::Text _text; 27 | #ifdef DEBUG 28 | sf::Text _stats; 29 | #endif 30 | }; 31 | } 32 | 33 | #endif // GAME_STATE_HPP 34 | -------------------------------------------------------------------------------- /src/state_machine.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STATE_MACHINE_HPP 2 | #define STATE_MACHINE_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include "state.hpp" 8 | 9 | namespace kg { 10 | typedef std::unique_ptr StateRef; 11 | 12 | class StateMachine { 13 | public: 14 | StateMachine() { } 15 | ~StateMachine() { } 16 | 17 | void addState(StateRef newState, bool isReplacing = true); 18 | void removeState(); 19 | // Run at start of each loop in Game.cpp 20 | void processStateChanges(); 21 | 22 | StateRef& getActiveState(); 23 | 24 | private: 25 | std::stack _states; 26 | StateRef _newState; 27 | 28 | bool _isRemoving; 29 | bool _isAdding, _isReplacing; 30 | }; 31 | } 32 | 33 | #endif // STATE_MACHINE_HPP 34 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project Configuration 2 | 3 | # Project name 4 | set(PNAME SfmlStarter) 5 | 6 | # SFML version - set the minimum version you'd like to use. 7 | set(SFML_VERSION 2.3) 8 | 9 | # SFML components - list all you want to use. 10 | # The provided framework requires graphics, window, and system. 11 | set(SFML_COMPONENTS graphics window system) 12 | 13 | # You shouldn't have to edit anything below this line to get started. 14 | 15 | cmake_minimum_required(VERSION 3.2) 16 | set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) 17 | 18 | project(${PNAME}) 19 | find_package(SFML ${SFML_VERSION} COMPONENTS ${SFML_COMPONENTS} REQUIRED) 20 | 21 | include_directories(${SFML_INCLUDE_DIR}) 22 | 23 | file(GLOB SOURCES "src/*.cpp") 24 | add_executable(${PNAME} ${SOURCES}) 25 | target_link_libraries(${PNAME} ${SFML_LIBRARIES} ${SFML_DEPENDENCIES}) 26 | 27 | set_property(TARGET ${PNAME} PROPERTY CXX_STANDARD 11) # Use C++11 28 | 29 | if(NOT WIN32 OR MINGW) 30 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # Show all warnings for GCC 31 | endif() 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Matthew Ross 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/game.hpp: -------------------------------------------------------------------------------- 1 | #ifndef GAME_HPP 2 | #define GAME_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "state_machine.hpp" 8 | #include "asset_manager.hpp" 9 | 10 | #define DEBUG 11 | 12 | namespace kg { 13 | struct GameData { 14 | StateMachine machine; 15 | sf::RenderWindow window; 16 | AssetManager assets; 17 | #ifdef DEBUG 18 | int FPS, UPS; 19 | #endif 20 | }; 21 | 22 | typedef std::shared_ptr GameDataRef; 23 | 24 | class Game { 25 | public: 26 | Game(int width, int height, std::string title); 27 | 28 | private: 29 | // Updates run at 30 per second. 30 | const float dt = 1.0f / 30.0f; 31 | sf::Clock _clock; 32 | #ifdef DEBUG 33 | sf::Clock _upsClock; 34 | sf::Clock _fpsClock; 35 | int _updates; 36 | int _frames; 37 | 38 | void calculateUpdatesPerSecond(); 39 | void calculateFramesPerSecond(); 40 | #endif 41 | GameDataRef _data = std::make_shared(); 42 | 43 | void run(); 44 | }; 45 | } 46 | 47 | #endif // GAME_HPP 48 | -------------------------------------------------------------------------------- /src/state_machine.cpp: -------------------------------------------------------------------------------- 1 | #include "state_machine.hpp" 2 | 3 | namespace kg { 4 | void StateMachine::addState(StateRef newState, bool isReplacing) { 5 | _isAdding = true; 6 | _isReplacing = isReplacing; 7 | 8 | _newState = std::move(newState); 9 | } 10 | 11 | void StateMachine::removeState() { 12 | _isRemoving = true; 13 | } 14 | 15 | void StateMachine::processStateChanges() { 16 | if (_isRemoving && !_states.empty()) { 17 | _states.pop(); 18 | 19 | if (!_states.empty()) { 20 | _states.top()->resume(); 21 | } 22 | _isRemoving = false; 23 | } 24 | 25 | if (_isAdding) { 26 | if (!_states.empty()) { 27 | if (_isReplacing) { 28 | _states.pop(); 29 | } else { 30 | _states.top()->pause(); 31 | } 32 | } 33 | 34 | _states.push(std::move(_newState)); 35 | _states.top()->init(); 36 | _isAdding = false; 37 | } 38 | } 39 | 40 | StateRef& StateMachine::getActiveState() { 41 | return _states.top(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/pause_state.cpp: -------------------------------------------------------------------------------- 1 | #include "pause_state.hpp" 2 | 3 | namespace kg { 4 | PauseState::PauseState(GameDataRef data) 5 | : _data(data) { } 6 | 7 | void PauseState::init() { 8 | _data->assets.loadFont("FiraMono", "assets/FiraMono-Regular.otf"); 9 | 10 | _text.setFont(_data->assets.getFont("FiraMono")); 11 | _text.setString("This is the Pause state! Esc to return to Game."); 12 | _text.setCharacterSize(24); 13 | _text.setColor(sf::Color::Red); 14 | _text.setPosition(4, _data->window.getSize().y - 30); 15 | } 16 | 17 | void PauseState::handleInput() { 18 | sf::Event evt; 19 | while (_data->window.pollEvent(evt)) { 20 | if (sf::Event::Closed == evt.type) { 21 | _data->window.close(); 22 | } 23 | 24 | if (sf::Event::KeyPressed == evt.type) { 25 | if (sf::Keyboard::Escape == evt.key.code) { 26 | _data->machine.removeState(); 27 | } 28 | } 29 | } 30 | } 31 | 32 | void PauseState::render(float dt) { 33 | _data->window.clear(sf::Color::Black); 34 | _data->window.draw(_text); 35 | _data->window.display(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SFML Starter 2 | 3 | A very simple starter setup for an [SFML](http://sfml-dev.org/) game with a minimal finite state machine (FSM). 4 | 5 | ## Use 6 | 7 | Clone the repo `git clone https://github.com/kiswa/SFML_Starter`, enter the directory you cloned into, and run `cmake .` (note the ` .` after the command). This should generate the necessary project files to build on your system. 8 | 9 | For Linux, follow this with `make` and you will have an executable named `sfml` which you can run to see the demo. 10 | 11 | ## What's Included 12 | 13 | All source files are in the `src` directory. 14 | 15 | * `main.cpp` The main entry point that starts everything going. 16 | * `game.*pp` The **Game** class contains a **GameData** struct that holds the FSM, Asset Manager, and SFML Window. 17 | * `asset_manager.*pp` The **AssetManager** class provides long-lived access to `sf::Texture`s and `sf::Font`s. 18 | * `state_machine.*pp` The **StateMachine** class is just a simple wrapper around a `std::stack` which handles transitioning between states. 19 | * `state.hpp` The **State** class is an abstract class that each state inherits. 20 | * `game_state.*pp` The **GameState** class is a *simple* implementation of a game state to show how it might be used. 21 | * `pause_state.*pp` The **PauseState** class is just to demonstrate changing states without replacing the current state. 22 | 23 | ### Credits 24 | 25 | The "alien" image is [courtesy of Kenney](http://www.kenney.nl/assets/alien-ufo-pack). 26 | 27 | The font used is [Fira Mono from Mozilla](https://github.com/mozilla/Fira/tree/master/otf) (specifically, `FiraMono-Regular.otf`). 28 | -------------------------------------------------------------------------------- /src/game.cpp: -------------------------------------------------------------------------------- 1 | #include "game.hpp" 2 | #include "game_state.hpp" 3 | 4 | namespace kg { 5 | Game::Game(int width, int height, std::string title) { 6 | _data->window.create(sf::VideoMode(width, height), title, 7 | sf::Style::Close | sf::Style::Titlebar); 8 | _data->machine.addState(StateRef(new GameState(_data))); 9 | 10 | run(); 11 | } 12 | 13 | void Game::run() { 14 | float newTime, frameTime, interpolation; 15 | 16 | float currentTime = _clock.getElapsedTime().asSeconds(); 17 | float accumulator = 0.0f; 18 | 19 | while (_data->window.isOpen()) { 20 | _data->machine.processStateChanges(); 21 | 22 | newTime = _clock.getElapsedTime().asSeconds(); 23 | frameTime = newTime - currentTime; 24 | 25 | if (frameTime > 0.25f) { 26 | frameTime = 0.25f; 27 | } 28 | 29 | currentTime = newTime; 30 | accumulator += frameTime; 31 | 32 | while (accumulator >= dt) { 33 | calculateUpdatesPerSecond(); 34 | 35 | _data->machine.getActiveState()->handleInput(); 36 | _data->machine.getActiveState()->update(dt); 37 | 38 | accumulator -= dt; 39 | } 40 | 41 | calculateFramesPerSecond(); 42 | 43 | interpolation = accumulator / dt; 44 | _data->machine.getActiveState()->render(interpolation); 45 | } 46 | } 47 | 48 | #ifdef DEBUG 49 | void Game::calculateUpdatesPerSecond() { 50 | _updates++; 51 | float time = _upsClock.getElapsedTime().asSeconds(); 52 | if (time >= 1.0f) { 53 | _data->UPS = _updates; 54 | 55 | _upsClock.restart(); 56 | _updates = 0; 57 | } 58 | } 59 | #endif 60 | 61 | #ifdef DEBUG 62 | void Game::calculateFramesPerSecond() { 63 | _frames++; 64 | float time = _fpsClock.getElapsedTime().asSeconds(); 65 | if (time >= 1.0f) { 66 | _data->FPS = _frames; 67 | 68 | _fpsClock.restart(); 69 | _frames = 0; 70 | } 71 | } 72 | #endif 73 | } 74 | -------------------------------------------------------------------------------- /src/game_state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "game_state.hpp" 3 | #include "pause_state.hpp" 4 | 5 | namespace kg { 6 | GameState::GameState(GameDataRef data) 7 | : _data(data) { } 8 | 9 | void GameState::init() { 10 | _data->assets.loadFont("FiraMono", "assets/FiraMono-Regular.otf"); 11 | _data->assets.loadTexture("alien", "assets/test.png"); 12 | 13 | _text.setFont(_data->assets.getFont("FiraMono")); 14 | _text.setString("This is the Game state! Esc to Pause"); 15 | _text.setCharacterSize(24); 16 | _text.setColor(sf::Color::Black); 17 | _text.setPosition(4, _data->window.getSize().y - 30); 18 | #ifdef DEBUG 19 | _stats.setFont(_data->assets.getFont("FiraMono")); 20 | _stats.setCharacterSize(12); 21 | _stats.setColor(sf::Color::Black); 22 | _stats.setPosition(4, 4); 23 | #endif 24 | _sprite.setTexture(_data->assets.getTexture("alien")); 25 | _sprite.setPosition(30, 30); 26 | _sprite.scale(0.5, 0.5); 27 | } 28 | 29 | void GameState::handleInput() { 30 | sf::Event evt; 31 | while (_data->window.pollEvent(evt)) { 32 | if (sf::Event::Closed == evt.type) { 33 | _data->window.close(); 34 | } 35 | 36 | if (sf::Event::KeyPressed == evt.type) { 37 | if (sf::Keyboard::Escape == evt.key.code) { 38 | _data->machine.addState(StateRef(new PauseState(_data)), 39 | false); 40 | } 41 | } 42 | } 43 | } 44 | 45 | void GameState::update(float dt) { 46 | float x = 0; 47 | float y = 0; 48 | 49 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::A)) { 50 | x -= 2; 51 | } 52 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::D)) { 53 | x += 2; 54 | } 55 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::W)) { 56 | y -= 2; 57 | } 58 | if (sf::Keyboard::isKeyPressed(sf::Keyboard::S)) { 59 | y += 2; 60 | } 61 | 62 | _sprite.move(x, y); 63 | } 64 | 65 | void GameState::render(float dt) { 66 | #ifdef DEBUG 67 | std::stringstream ss; 68 | ss << "UPS: " << _data->UPS << " FPS: " << _data->FPS << " (approx.)"; 69 | _stats.setString(ss.str()); 70 | #endif 71 | _data->window.clear(sf::Color::Red); 72 | _data->window.draw(_sprite); 73 | _data->window.draw(_text); 74 | #ifdef DEBUG 75 | _data->window.draw(_stats); // Show "UPS: # FPS: #" 76 | #endif 77 | _data->window.display(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /assets/LICENSE: -------------------------------------------------------------------------------- 1 | Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. 2 | with Reserved Font Name < Fira >, 3 | 4 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 5 | This license is copied below, and is also available with a FAQ at: 6 | http://scripts.sil.org/OFL 7 | 8 | 9 | ----------------------------------------------------------- 10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 11 | ----------------------------------------------------------- 12 | 13 | PREAMBLE 14 | The goals of the Open Font License (OFL) are to stimulate worldwide 15 | development of collaborative font projects, to support the font creation 16 | efforts of academic and linguistic communities, and to provide a free and 17 | open framework in which fonts may be shared and improved in partnership 18 | with others. 19 | 20 | The OFL allows the licensed fonts to be used, studied, modified and 21 | redistributed freely as long as they are not sold by themselves. The 22 | fonts, including any derivative works, can be bundled, embedded, 23 | redistributed and/or sold with any software provided that any reserved 24 | names are not used by derivative works. The fonts and derivatives, 25 | however, cannot be released under any other type of license. The 26 | requirement for fonts to remain under this license does not apply 27 | to any document created using the fonts or their derivatives. 28 | 29 | DEFINITIONS 30 | "Font Software" refers to the set of files released by the Copyright 31 | Holder(s) under this license and clearly marked as such. This may 32 | include source files, build scripts and documentation. 33 | 34 | "Reserved Font Name" refers to any names specified as such after the 35 | copyright statement(s). 36 | 37 | "Original Version" refers to the collection of Font Software components as 38 | distributed by the Copyright Holder(s). 39 | 40 | "Modified Version" refers to any derivative made by adding to, deleting, 41 | or substituting -- in part or in whole -- any of the components of the 42 | Original Version, by changing formats or by porting the Font Software to a 43 | new environment. 44 | 45 | "Author" refers to any designer, engineer, programmer, technical 46 | writer or other person who contributed to the Font Software. 47 | 48 | PERMISSION & CONDITIONS 49 | Permission is hereby granted, free of charge, to any person obtaining 50 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 51 | redistribute, and sell modified and unmodified copies of the Font 52 | Software, subject to the following conditions: 53 | 54 | 1) Neither the Font Software nor any of its individual components, 55 | in Original or Modified Versions, may be sold by itself. 56 | 57 | 2) Original or Modified Versions of the Font Software may be bundled, 58 | redistributed and/or sold with any software, provided that each copy 59 | contains the above copyright notice and this license. These can be 60 | included either as stand-alone text files, human-readable headers or 61 | in the appropriate machine-readable metadata fields within text or 62 | binary files as long as those fields can be easily viewed by the user. 63 | 64 | 3) No Modified Version of the Font Software may use the Reserved Font 65 | Name(s) unless explicit written permission is granted by the corresponding 66 | Copyright Holder. This restriction only applies to the primary font name as 67 | presented to the users. 68 | 69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 70 | Software shall not be used to promote, endorse or advertise any 71 | Modified Version, except to acknowledge the contribution(s) of the 72 | Copyright Holder(s) and the Author(s) or with their explicit written 73 | permission. 74 | 75 | 5) The Font Software, modified or unmodified, in part or in whole, 76 | must be distributed entirely under this license, and must not be 77 | distributed under any other license. The requirement for fonts to 78 | remain under this license does not apply to any document created 79 | using the Font Software. 80 | 81 | TERMINATION 82 | This license becomes null and void if any of the above conditions are 83 | not met. 84 | 85 | DISCLAIMER 86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 94 | OTHER DEALINGS IN THE FONT SOFTWARE. 95 | -------------------------------------------------------------------------------- /cmake/FindSFML.cmake: -------------------------------------------------------------------------------- 1 | # This script locates the SFML library 2 | # ------------------------------------ 3 | # 4 | # Usage 5 | # ----- 6 | # 7 | # When you try to locate the SFML libraries, you must specify which modules you want to use (system, window, graphics, network, audio, main). 8 | # If none is given, the SFML_LIBRARIES variable will be empty and you'll end up linking to nothing. 9 | # example: 10 | # find_package(SFML COMPONENTS graphics window system) // find the graphics, window and system modules 11 | # 12 | # You can enforce a specific version, either MAJOR.MINOR or only MAJOR. 13 | # If nothing is specified, the version won't be checked (i.e. any version will be accepted). 14 | # example: 15 | # find_package(SFML COMPONENTS ...) // no specific version required 16 | # find_package(SFML 2 COMPONENTS ...) // any 2.x version 17 | # find_package(SFML 2.4 COMPONENTS ...) // version 2.4 or greater 18 | # 19 | # By default, the dynamic libraries of SFML will be found. To find the static ones instead, 20 | # you must set the SFML_STATIC_LIBRARIES variable to TRUE before calling find_package(SFML ...). 21 | # Since you have to link yourself all the SFML dependencies when you link it statically, the following 22 | # additional variables are defined: SFML_XXX_DEPENDENCIES and SFML_DEPENDENCIES (see their detailed 23 | # description below). 24 | # In case of static linking, the SFML_STATIC macro will also be defined by this script. 25 | # example: 26 | # set(SFML_STATIC_LIBRARIES TRUE) 27 | # find_package(SFML 2 COMPONENTS network system) 28 | # 29 | # On Mac OS X if SFML_STATIC_LIBRARIES is not set to TRUE then by default CMake will search for frameworks unless 30 | # CMAKE_FIND_FRAMEWORK is set to "NEVER" for example. Please refer to CMake documentation for more details. 31 | # Moreover, keep in mind that SFML frameworks are only available as release libraries unlike dylibs which 32 | # are available for both release and debug modes. 33 | # 34 | # If SFML is not installed in a standard path, you can use the SFML_ROOT CMake (or environment) variable 35 | # to tell CMake where SFML is. 36 | # 37 | # Output 38 | # ------ 39 | # 40 | # This script defines the following variables: 41 | # - For each specified module XXX (system, window, graphics, network, audio, main): 42 | # - SFML_XXX_LIBRARY_DEBUG: the name of the debug library of the xxx module (set to SFML_XXX_LIBRARY_RELEASE is no debug version is found) 43 | # - SFML_XXX_LIBRARY_RELEASE: the name of the release library of the xxx module (set to SFML_XXX_LIBRARY_DEBUG is no release version is found) 44 | # - SFML_XXX_LIBRARY: the name of the library to link to for the xxx module (includes both debug and optimized names if necessary) 45 | # - SFML_XXX_FOUND: true if either the debug or release library of the xxx module is found 46 | # - SFML_XXX_DEPENDENCIES: the list of libraries the module depends on, in case of static linking 47 | # - SFML_LIBRARIES: the list of all libraries corresponding to the required modules 48 | # - SFML_FOUND: true if all the required modules are found 49 | # - SFML_INCLUDE_DIR: the path where SFML headers are located (the directory containing the SFML/Config.hpp file) 50 | # - SFML_DEPENDENCIES: the list of libraries SFML depends on, in case of static linking 51 | # 52 | # example: 53 | # find_package(SFML 2 COMPONENTS system window graphics audio REQUIRED) 54 | # include_directories(${SFML_INCLUDE_DIR}) 55 | # add_executable(myapp ...) 56 | # target_link_libraries(myapp ${SFML_LIBRARIES}) 57 | 58 | # define the SFML_STATIC macro if static build was chosen 59 | if(SFML_STATIC_LIBRARIES) 60 | add_definitions(-DSFML_STATIC) 61 | endif() 62 | 63 | # define the list of search paths for headers and libraries 64 | set(FIND_SFML_PATHS 65 | ${SFML_ROOT} 66 | $ENV{SFML_ROOT} 67 | ~/Library/Frameworks 68 | /Library/Frameworks 69 | /usr/local 70 | /usr 71 | /sw 72 | /opt/local 73 | /opt/csw 74 | /opt) 75 | 76 | # find the SFML include directory 77 | find_path(SFML_INCLUDE_DIR SFML/Config.hpp 78 | PATH_SUFFIXES include 79 | PATHS ${FIND_SFML_PATHS}) 80 | 81 | # check the version number 82 | set(SFML_VERSION_OK TRUE) 83 | if(SFML_FIND_VERSION AND SFML_INCLUDE_DIR) 84 | # extract the major and minor version numbers from SFML/Config.hpp 85 | # we have to handle framework a little bit differently: 86 | if("${SFML_INCLUDE_DIR}" MATCHES "SFML.framework") 87 | set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/Headers/Config.hpp") 88 | else() 89 | set(SFML_CONFIG_HPP_INPUT "${SFML_INCLUDE_DIR}/SFML/Config.hpp") 90 | endif() 91 | FILE(READ "${SFML_CONFIG_HPP_INPUT}" SFML_CONFIG_HPP_CONTENTS) 92 | STRING(REGEX MATCH ".*#define SFML_VERSION_MAJOR ([0-9]+).*#define SFML_VERSION_MINOR ([0-9]+).*#define SFML_VERSION_PATCH ([0-9]+).*" SFML_CONFIG_HPP_CONTENTS "${SFML_CONFIG_HPP_CONTENTS}") 93 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MAJOR ([0-9]+).*" "\\1" SFML_VERSION_MAJOR "${SFML_CONFIG_HPP_CONTENTS}") 94 | STRING(REGEX REPLACE ".*#define SFML_VERSION_MINOR ([0-9]+).*" "\\1" SFML_VERSION_MINOR "${SFML_CONFIG_HPP_CONTENTS}") 95 | STRING(REGEX REPLACE ".*#define SFML_VERSION_PATCH ([0-9]+).*" "\\1" SFML_VERSION_PATCH "${SFML_CONFIG_HPP_CONTENTS}") 96 | math(EXPR SFML_REQUESTED_VERSION "${SFML_FIND_VERSION_MAJOR} * 10000 + ${SFML_FIND_VERSION_MINOR} * 100 + ${SFML_FIND_VERSION_PATCH}") 97 | 98 | # if we could extract them, compare with the requested version number 99 | if (SFML_VERSION_MAJOR) 100 | # transform version numbers to an integer 101 | math(EXPR SFML_VERSION "${SFML_VERSION_MAJOR} * 10000 + ${SFML_VERSION_MINOR} * 100 + ${SFML_VERSION_PATCH}") 102 | 103 | # compare them 104 | if(SFML_VERSION LESS SFML_REQUESTED_VERSION) 105 | set(SFML_VERSION_OK FALSE) 106 | endif() 107 | else() 108 | # SFML version is < 2.0 109 | if (SFML_REQUESTED_VERSION GREATER 10900) 110 | set(SFML_VERSION_OK FALSE) 111 | set(SFML_VERSION_MAJOR 1) 112 | set(SFML_VERSION_MINOR x) 113 | set(SFML_VERSION_PATCH x) 114 | endif() 115 | endif() 116 | endif() 117 | 118 | # find the requested modules 119 | set(SFML_FOUND TRUE) # will be set to false if one of the required modules is not found 120 | foreach(FIND_SFML_COMPONENT ${SFML_FIND_COMPONENTS}) 121 | string(TOLOWER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_LOWER) 122 | string(TOUPPER ${FIND_SFML_COMPONENT} FIND_SFML_COMPONENT_UPPER) 123 | set(FIND_SFML_COMPONENT_NAME sfml-${FIND_SFML_COMPONENT_LOWER}) 124 | 125 | # no suffix for sfml-main, it is always a static library 126 | if(FIND_SFML_COMPONENT_LOWER STREQUAL "main") 127 | # release library 128 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 129 | NAMES ${FIND_SFML_COMPONENT_NAME} 130 | PATH_SUFFIXES lib64 lib 131 | PATHS ${FIND_SFML_PATHS}) 132 | 133 | # debug library 134 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG 135 | NAMES ${FIND_SFML_COMPONENT_NAME}-d 136 | PATH_SUFFIXES lib64 lib 137 | PATHS ${FIND_SFML_PATHS}) 138 | else() 139 | # static release library 140 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE 141 | NAMES ${FIND_SFML_COMPONENT_NAME}-s 142 | PATH_SUFFIXES lib64 lib 143 | PATHS ${FIND_SFML_PATHS}) 144 | 145 | # static debug library 146 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG 147 | NAMES ${FIND_SFML_COMPONENT_NAME}-s-d 148 | PATH_SUFFIXES lib64 lib 149 | PATHS ${FIND_SFML_PATHS}) 150 | 151 | # dynamic release library 152 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE 153 | NAMES ${FIND_SFML_COMPONENT_NAME} 154 | PATH_SUFFIXES lib64 lib 155 | PATHS ${FIND_SFML_PATHS}) 156 | 157 | # dynamic debug library 158 | find_library(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG 159 | NAMES ${FIND_SFML_COMPONENT_NAME}-d 160 | PATH_SUFFIXES lib64 lib 161 | PATHS ${FIND_SFML_PATHS}) 162 | 163 | # choose the entries that fit the requested link type 164 | if(SFML_STATIC_LIBRARIES) 165 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE) 166 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE}) 167 | endif() 168 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG) 169 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG}) 170 | endif() 171 | else() 172 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE) 173 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE}) 174 | endif() 175 | if(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) 176 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG}) 177 | endif() 178 | endif() 179 | endif() 180 | 181 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG OR SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 182 | # library found 183 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND TRUE) 184 | 185 | # if both are found, set SFML_XXX_LIBRARY to contain both 186 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 187 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY debug ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG} 188 | optimized ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 189 | endif() 190 | 191 | # if only one debug/release variant is found, set the other to be equal to the found one 192 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE) 193 | # debug and not release 194 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 195 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG}) 196 | endif() 197 | if (SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE AND NOT SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG) 198 | # release and not debug 199 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 200 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY ${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE}) 201 | endif() 202 | else() 203 | # library not found 204 | set(SFML_FOUND FALSE) 205 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_FOUND FALSE) 206 | set(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY "") 207 | set(FIND_SFML_MISSING "${FIND_SFML_MISSING} SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY") 208 | endif() 209 | 210 | # mark as advanced 211 | MARK_AS_ADVANCED(SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY 212 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_RELEASE 213 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DEBUG 214 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_RELEASE 215 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_STATIC_DEBUG 216 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_RELEASE 217 | SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY_DYNAMIC_DEBUG) 218 | 219 | # add to the global list of libraries 220 | set(SFML_LIBRARIES ${SFML_LIBRARIES} "${SFML_${FIND_SFML_COMPONENT_UPPER}_LIBRARY}") 221 | endforeach() 222 | 223 | # in case of static linking, we must also define the list of all the dependencies of SFML libraries 224 | if(SFML_STATIC_LIBRARIES) 225 | 226 | # detect the OS 227 | if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") 228 | set(FIND_SFML_OS_WINDOWS 1) 229 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") 230 | set(FIND_SFML_OS_LINUX 1) 231 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") 232 | set(FIND_SFML_OS_FREEBSD 1) 233 | elseif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") 234 | set(FIND_SFML_OS_MACOSX 1) 235 | endif() 236 | 237 | # start with an empty list 238 | set(SFML_DEPENDENCIES) 239 | set(FIND_SFML_DEPENDENCIES_NOTFOUND) 240 | 241 | # macro that searches for a 3rd-party library 242 | macro(find_sfml_dependency output friendlyname) 243 | # No lookup in environment variables (PATH on Windows), as they may contain wrong library versions 244 | find_library(${output} NAMES ${ARGN} PATHS ${FIND_SFML_PATHS} PATH_SUFFIXES lib NO_SYSTEM_ENVIRONMENT_PATH) 245 | if(${${output}} STREQUAL "${output}-NOTFOUND") 246 | unset(output) 247 | set(FIND_SFML_DEPENDENCIES_NOTFOUND "${FIND_SFML_DEPENDENCIES_NOTFOUND} ${friendlyname}") 248 | endif() 249 | endmacro() 250 | 251 | # sfml-system 252 | list(FIND SFML_FIND_COMPONENTS "system" FIND_SFML_SYSTEM_COMPONENT) 253 | if(NOT ${FIND_SFML_SYSTEM_COMPONENT} EQUAL -1) 254 | 255 | # update the list -- these are only system libraries, no need to find them 256 | if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD OR FIND_SFML_OS_MACOSX) 257 | set(SFML_SYSTEM_DEPENDENCIES "pthread") 258 | endif() 259 | if(FIND_SFML_OS_LINUX) 260 | set(SFML_SYSTEM_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} "rt") 261 | endif() 262 | if(FIND_SFML_OS_WINDOWS) 263 | set(SFML_SYSTEM_DEPENDENCIES "winmm") 264 | endif() 265 | set(SFML_DEPENDENCIES ${SFML_SYSTEM_DEPENDENCIES} ${SFML_DEPENDENCIES}) 266 | endif() 267 | 268 | # sfml-network 269 | list(FIND SFML_FIND_COMPONENTS "network" FIND_SFML_NETWORK_COMPONENT) 270 | if(NOT ${FIND_SFML_NETWORK_COMPONENT} EQUAL -1) 271 | 272 | # update the list -- these are only system libraries, no need to find them 273 | if(FIND_SFML_OS_WINDOWS) 274 | set(SFML_NETWORK_DEPENDENCIES "ws2_32") 275 | endif() 276 | set(SFML_DEPENDENCIES ${SFML_NETWORK_DEPENDENCIES} ${SFML_DEPENDENCIES}) 277 | endif() 278 | 279 | # sfml-window 280 | list(FIND SFML_FIND_COMPONENTS "window" FIND_SFML_WINDOW_COMPONENT) 281 | if(NOT ${FIND_SFML_WINDOW_COMPONENT} EQUAL -1) 282 | 283 | # find libraries 284 | if(FIND_SFML_OS_LINUX OR FIND_SFML_OS_FREEBSD) 285 | find_sfml_dependency(X11_LIBRARY "X11" X11) 286 | find_sfml_dependency(LIBXCB_LIBRARIES "XCB" xcb libxcb) 287 | find_sfml_dependency(X11_XCB_LIBRARY "X11-xcb" X11-xcb libX11-xcb) 288 | find_sfml_dependency(XCB_RANDR_LIBRARY "xcb-randr" xcb-randr libxcb-randr) 289 | find_sfml_dependency(XCB_IMAGE_LIBRARY "xcb-image" xcb-image libxcb-image) 290 | endif() 291 | 292 | if(FIND_SFML_OS_LINUX) 293 | find_sfml_dependency(UDEV_LIBRARIES "UDev" udev libudev) 294 | endif() 295 | 296 | # update the list 297 | if(FIND_SFML_OS_WINDOWS) 298 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "opengl32" "winmm" "gdi32") 299 | elseif(FIND_SFML_OS_LINUX) 300 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${LIBXCB_LIBRARIES} ${X11_XCB_LIBRARY} ${XCB_RANDR_LIBRARY} ${XCB_IMAGE_LIBRARY} ${UDEV_LIBRARIES}) 301 | elseif(FIND_SFML_OS_FREEBSD) 302 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "GL" ${X11_LIBRARY} ${LIBXCB_LIBRARIES} ${X11_XCB_LIBRARY} ${XCB_RANDR_LIBRARY} ${XCB_IMAGE_LIBRARY} "usbhid") 303 | elseif(FIND_SFML_OS_MACOSX) 304 | set(SFML_WINDOW_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} "-framework OpenGL -framework Foundation -framework AppKit -framework IOKit -framework Carbon") 305 | endif() 306 | set(SFML_DEPENDENCIES ${SFML_WINDOW_DEPENDENCIES} ${SFML_DEPENDENCIES}) 307 | endif() 308 | 309 | # sfml-graphics 310 | list(FIND SFML_FIND_COMPONENTS "graphics" FIND_SFML_GRAPHICS_COMPONENT) 311 | if(NOT ${FIND_SFML_GRAPHICS_COMPONENT} EQUAL -1) 312 | 313 | # find libraries 314 | find_sfml_dependency(FREETYPE_LIBRARY "FreeType" freetype) 315 | find_sfml_dependency(JPEG_LIBRARY "libjpeg" jpeg) 316 | 317 | # update the list 318 | set(SFML_GRAPHICS_DEPENDENCIES ${FREETYPE_LIBRARY} ${JPEG_LIBRARY}) 319 | set(SFML_DEPENDENCIES ${SFML_GRAPHICS_DEPENDENCIES} ${SFML_DEPENDENCIES}) 320 | endif() 321 | 322 | # sfml-audio 323 | list(FIND SFML_FIND_COMPONENTS "audio" FIND_SFML_AUDIO_COMPONENT) 324 | if(NOT ${FIND_SFML_AUDIO_COMPONENT} EQUAL -1) 325 | 326 | # find libraries 327 | find_sfml_dependency(OPENAL_LIBRARY "OpenAL" openal openal32) 328 | find_sfml_dependency(OGG_LIBRARY "Ogg" ogg) 329 | find_sfml_dependency(VORBIS_LIBRARY "Vorbis" vorbis) 330 | find_sfml_dependency(VORBISFILE_LIBRARY "VorbisFile" vorbisfile) 331 | find_sfml_dependency(VORBISENC_LIBRARY "VorbisEnc" vorbisenc) 332 | find_sfml_dependency(FLAC_LIBRARY "FLAC" flac) 333 | 334 | # update the list 335 | set(SFML_AUDIO_DEPENDENCIES ${OPENAL_LIBRARY} ${FLAC_LIBRARY} ${VORBISENC_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY}) 336 | set(SFML_DEPENDENCIES ${SFML_DEPENDENCIES} ${SFML_AUDIO_DEPENDENCIES}) 337 | endif() 338 | 339 | endif() 340 | 341 | # handle errors 342 | if(NOT SFML_VERSION_OK) 343 | # SFML version not ok 344 | set(FIND_SFML_ERROR "SFML found but version too low (requested: ${SFML_FIND_VERSION}, found: ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH})") 345 | set(SFML_FOUND FALSE) 346 | elseif(SFML_STATIC_LIBRARIES AND FIND_SFML_DEPENDENCIES_NOTFOUND) 347 | set(FIND_SFML_ERROR "SFML found but some of its dependencies are missing (${FIND_SFML_DEPENDENCIES_NOTFOUND})") 348 | set(SFML_FOUND FALSE) 349 | elseif(NOT SFML_FOUND) 350 | # include directory or library not found 351 | set(FIND_SFML_ERROR "Could NOT find SFML (missing: ${FIND_SFML_MISSING})") 352 | endif() 353 | if (NOT SFML_FOUND) 354 | if(SFML_FIND_REQUIRED) 355 | # fatal error 356 | message(FATAL_ERROR ${FIND_SFML_ERROR}) 357 | elseif(NOT SFML_FIND_QUIETLY) 358 | # error but continue 359 | message("${FIND_SFML_ERROR}") 360 | endif() 361 | endif() 362 | 363 | # handle success 364 | if(SFML_FOUND AND NOT SFML_FIND_QUIETLY) 365 | message(STATUS "Found SFML ${SFML_VERSION_MAJOR}.${SFML_VERSION_MINOR}.${SFML_VERSION_PATCH} in ${SFML_INCLUDE_DIR}") 366 | endif() 367 | --------------------------------------------------------------------------------