├── .gitignore ├── rsrc ├── test.png ├── tileset.png ├── spritesheet-info.json └── map.json ├── .gitmodules ├── config.h ├── docs ├── _config.yml ├── _layouts │ └── home.html └── index.md ├── include └── sge │ ├── engine-forward.hpp │ ├── assets │ ├── loader-forward.hpp │ ├── locators │ │ └── file.hpp │ ├── locator.hpp │ ├── loader.hpp │ ├── loaders │ │ ├── image.hpp │ │ ├── json.hpp │ │ ├── audio.hpp │ │ └── font.hpp │ ├── cache.hpp │ ├── asset.hpp │ └── manager.hpp │ ├── initializers │ ├── sdl.hpp │ ├── sdl-fonts.hpp │ ├── sdl-image.hpp │ ├── sdl-mixer.hpp │ └── sdl-window.hpp │ ├── physics │ ├── manifold.hpp │ └── manager.hpp │ ├── error.hpp │ ├── sge.hpp │ ├── nodes │ ├── body.hpp │ ├── boundingbox.hpp │ ├── collisionshape.hpp │ ├── sprite.hpp │ ├── label.hpp │ ├── tilemap.hpp │ ├── animatedsprite.hpp │ ├── canvas.hpp │ └── position.hpp │ ├── timer.hpp │ ├── utils │ ├── callback.hpp │ ├── shape.hpp │ ├── vector.hpp │ └── matrix.hpp │ ├── nodemgr.hpp │ ├── config.hpp │ ├── init.hpp │ ├── actionmgr.hpp │ ├── scenemgr.hpp │ ├── mainloop.hpp │ ├── audiomgr.hpp │ ├── node.hpp │ ├── engine.hpp │ └── renderer.hpp ├── src ├── nodes │ ├── body.cpp │ ├── boundingbox.cpp │ ├── collisionshape.cpp │ ├── label.cpp │ ├── sprite.cpp │ ├── canvas.cpp │ ├── animatedsprite.cpp │ ├── position.cpp │ └── tilemap.cpp ├── initializers │ ├── sdl-fonts.cpp │ ├── sdl.cpp │ ├── sdl-image.cpp │ ├── sdl-mixer.cpp │ └── sdl-window.cpp ├── utils │ ├── vector.cpp │ └── shape.cpp ├── assets │ ├── loaders │ │ ├── image.cpp │ │ ├── json.cpp │ │ ├── font.cpp │ │ └── audio.cpp │ ├── manager.cpp │ ├── locators │ │ └── file.cpp │ └── asset.cpp ├── init.cpp ├── config.cpp ├── scenemgr.cpp ├── physics │ └── manager.cpp ├── mainloop.cpp ├── actionmgr.cpp ├── engine.cpp ├── audiomgr.cpp ├── node.cpp └── renderer.cpp ├── cmake ├── FindSDL2.cmake ├── FindSDL2_ttf.cmake ├── FindSDL2_mixer.cmake ├── FindSDL2_gfx.cmake └── FindSDL2_image.cmake ├── LICENSE ├── test.cpp ├── README.md └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | __build__ -------------------------------------------------------------------------------- /rsrc/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkdd/sdl-game-engine/HEAD/rsrc/test.png -------------------------------------------------------------------------------- /rsrc/tileset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/linkdd/sdl-game-engine/HEAD/rsrc/tileset.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/json"] 2 | path = lib/json 3 | url = https://github.com/nlohmann/json.git 4 | -------------------------------------------------------------------------------- /config.h: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_CONFIG_H 2 | #define __SGE_CONFIG_H 3 | 4 | #define SGE_SOURCE_DIR "@sge_SOURCE_DIR@"s 5 | 6 | #endif /* __SGE_CONFIG_H */ -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-tactile 2 | title: SDLGameEngine 3 | description: 2D Game Engine built on top of SDL2 4 | show_downloads: true 5 | -------------------------------------------------------------------------------- /include/sge/engine-forward.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ENGINE_FORWARD_HPP 2 | #define __SGE_ENGINE_FORWARD_HPP 3 | 4 | namespace sge 5 | { 6 | class Engine; 7 | } 8 | 9 | #endif /* __SGE_ENGINE_FORWARD_HPP */ 10 | -------------------------------------------------------------------------------- /include/sge/assets/loader-forward.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_LOADER_FORWARD_HPP 2 | #define __SGE_LOADER_FORWARD_HPP 3 | 4 | namespace sge 5 | { 6 | class AssetLoader; 7 | } 8 | 9 | #endif /* __SGE_LOADER_FORWARD_HPP */ 10 | -------------------------------------------------------------------------------- /rsrc/spritesheet-info.json: -------------------------------------------------------------------------------- 1 | { 2 | "spritesheet": { 3 | "resource": "rsrc/spritesheet.png", 4 | "width": 32, 5 | "height": 32, 6 | "spacing": 0 7 | }, 8 | "rate": 24, 9 | "nframes": 4, 10 | "frames": [ 11 | [0, 0], 12 | [0, 1], 13 | [0, 2], 14 | [0, 3] 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /include/sge/initializers/sdl.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SDL_INIT_HPP 2 | #define __SGE_SDL_INIT_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class SDLInitializer : public Initializer 9 | { 10 | public: 11 | void do_initialize(); 12 | void do_shutdown(); 13 | }; 14 | } 15 | 16 | #endif /* __SGE_SDL_INIT_HPP */ 17 | -------------------------------------------------------------------------------- /src/nodes/body.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | namespace sge 7 | { 8 | vector BodyNode::mro() const 9 | { 10 | auto _mro = PositionNode::mro(); 11 | _mro.push_back("BodyNode"); 12 | return _mro; 13 | } 14 | 15 | void BodyNode::colliding(const Manifold &) {} 16 | } 17 | -------------------------------------------------------------------------------- /include/sge/initializers/sdl-fonts.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SDL_FONTS_INIT_HPP 2 | #define __SGE_SDL_FONTS_INIT_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class SDLFontsInitializer : public Initializer 9 | { 10 | public: 11 | void do_initialize(); 12 | void do_shutdown(); 13 | }; 14 | } 15 | 16 | #endif /* __SGE_SDL_FONTS_INIT_HPP */ 17 | -------------------------------------------------------------------------------- /include/sge/initializers/sdl-image.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SDL_IMAGE_INIT_HPP 2 | #define __SGE_SDL_IMAGE_INIT_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class SDLImageInitializer : public Initializer 9 | { 10 | public: 11 | void do_initialize(); 12 | void do_shutdown(); 13 | }; 14 | } 15 | 16 | #endif /* __SGE_SDL_IMAGE_INIT_HPP */ 17 | -------------------------------------------------------------------------------- /include/sge/physics/manifold.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_MANIFOLD_HPP 2 | #define __SGE_MANIFOLD_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | struct Manifold 11 | { 12 | std::shared_ptr a; 13 | std::shared_ptr b; 14 | Vector mtv; 15 | }; 16 | } 17 | 18 | #endif /* __SGE_MANIFOLD_HPP */ 19 | -------------------------------------------------------------------------------- /src/initializers/sdl-fonts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | void SDLFontsInitializer::do_initialize() 9 | { 10 | if (TTF_Init() != 0) 11 | { 12 | throw InitError("SDL_ttf", TTF_GetError()); 13 | } 14 | } 15 | 16 | void SDLFontsInitializer::do_shutdown() 17 | { 18 | TTF_Quit(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/initializers/sdl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace sge 5 | { 6 | void SDLInitializer::do_initialize() 7 | { 8 | SDL_SetMainReady(); 9 | 10 | if (SDL_Init(SDL_INIT_EVERYTHING) != 0) 11 | { 12 | throw InitError("SDL", SDL_GetError()); 13 | } 14 | } 15 | 16 | void SDLInitializer::do_shutdown() 17 | { 18 | SDL_Quit(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /include/sge/error.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_EXCEPTION_HPP 2 | #define __SGE_EXCEPTION_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class Exception : public std::runtime_error 10 | { 11 | public: 12 | Exception(const std::string &domain, const std::string &msg) throw() : runtime_error("[" + domain + "] " + msg) {} 13 | virtual ~Exception() noexcept {} 14 | }; 15 | } 16 | 17 | #endif /* __SGE_EXCEPTION_HPP */ 18 | -------------------------------------------------------------------------------- /include/sge/physics/manager.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_PHYSIC_MANAGER_HPP 2 | #define __SGE_PHYSIC_MANAGER_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class PhysicManager 10 | { 11 | public: 12 | PhysicManager(Engine &engine); 13 | 14 | void process_handler(Uint32 delta); 15 | 16 | private: 17 | Engine &engine; 18 | }; 19 | } 20 | 21 | #endif /* __SGE_PHYSIC_MANAGER_HPP */ 22 | -------------------------------------------------------------------------------- /include/sge/sge.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_HPP 2 | #define __SGE_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #endif /* __SGE_HPP */ 18 | -------------------------------------------------------------------------------- /include/sge/nodes/body.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_BODY_NODE_HPP 2 | #define __SGE_BODY_NODE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class BodyNode : public PositionNode 10 | { 11 | using PositionNode::PositionNode; 12 | 13 | public: 14 | virtual std::vector mro() const; 15 | 16 | virtual void colliding(const Manifold &manifold); 17 | }; 18 | } 19 | 20 | #endif /* __SGE_BODY_NODE_HPP */ 21 | -------------------------------------------------------------------------------- /include/sge/assets/locators/file.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_FILE_LOCATOR_HPP 2 | #define __SGE_FILE_LOCATOR_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class FileLocator : public AssetLocator 9 | { 10 | public: 11 | FileLocator(const std::string &location); 12 | 13 | virtual SDL_RWops *locate(const std::string &assetname, bool binary); 14 | 15 | private: 16 | std::string _location; 17 | }; 18 | } 19 | 20 | #endif /* __SGE_FILE_LOCATOR_HPP */ 21 | -------------------------------------------------------------------------------- /include/sge/assets/locator.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ASSET_LOCATOR_HPP 2 | #define __SGE_ASSET_LOCATOR_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace sge 10 | { 11 | class AssetLocatorError : public Exception 12 | { 13 | using Exception::Exception; 14 | }; 15 | 16 | class AssetLocator 17 | { 18 | public: 19 | virtual SDL_RWops *locate(const std::string &assetname, bool binary) = 0; 20 | }; 21 | } 22 | 23 | #endif /* __SGE_ASSET_LOCATOR_HPP */ 24 | -------------------------------------------------------------------------------- /src/utils/vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace sge 4 | { 5 | Vector VectorPolar(float angle, float r) 6 | { 7 | return Vector( 8 | r * cos(angle), 9 | r * sin(angle) 10 | ); 11 | } 12 | 13 | Vector operator*(int i, const Vector &v) 14 | { 15 | return v * i; 16 | } 17 | 18 | Vector operator*(float f, const Vector &v) 19 | { 20 | return v * f; 21 | } 22 | 23 | Vector operator-(const Vector &v) 24 | { 25 | return -1 * v; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /docs/_layouts/home.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | 8 | Become a Patron! 9 | 10 | 11 |
12 | 13 |
14 | 15 | 16 | 17 |
18 | 19 | {{ content }} 20 | -------------------------------------------------------------------------------- /include/sge/timer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_TIMER_HPP 2 | #define __SGE_TIMER_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class Timer 9 | { 10 | public: 11 | Timer() : ticks(0) {} 12 | 13 | void start() 14 | { 15 | ticks = SDL_GetTicks(); 16 | } 17 | 18 | Uint32 get_ticks() 19 | { 20 | return SDL_GetTicks() - ticks; 21 | } 22 | 23 | private: 24 | Uint32 ticks; 25 | }; 26 | } 27 | 28 | #endif /* __SGE_TIMER_HPP */ 29 | -------------------------------------------------------------------------------- /src/initializers/sdl-image.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | const int IMG_INIT_EVERYTHING = IMG_INIT_JPG | IMG_INIT_PNG; 9 | 10 | void SDLImageInitializer::do_initialize() 11 | { 12 | if ((IMG_Init(IMG_INIT_EVERYTHING) & IMG_INIT_EVERYTHING) != IMG_INIT_EVERYTHING) 13 | { 14 | throw InitError("SDL_image", IMG_GetError()); 15 | } 16 | } 17 | 18 | void SDLImageInitializer::do_shutdown() 19 | { 20 | IMG_Quit(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /include/sge/utils/callback.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_CALLBACK_HPP 2 | #define __SGE_CALLBACK_HPP 3 | 4 | #include 5 | 6 | template 7 | struct Callback; 8 | 9 | template 10 | struct Callback 11 | { 12 | template 13 | static Ret callback(Args... args) 14 | { 15 | return func(args...); 16 | } 17 | 18 | static std::function func; 19 | }; 20 | 21 | template 22 | std::function Callback::func; 23 | 24 | #endif /* __SGE_CALLBACK_HPP */ -------------------------------------------------------------------------------- /include/sge/assets/loader.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ASSET_LOADER_HPP 2 | #define __SGE_ASSET_LOADER_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace sge 12 | { 13 | class AssetLoaderError : public Exception 14 | { 15 | using Exception::Exception; 16 | }; 17 | 18 | class AssetLoader 19 | { 20 | public: 21 | virtual void load(std::shared_ptr asset, SDL_RWops *input) = 0; 22 | virtual void unload(BaseAsset *asset) = 0; 23 | }; 24 | } 25 | 26 | #endif /* __SGE_ASSET_LOADER_HPP */ 27 | -------------------------------------------------------------------------------- /rsrc/map.json: -------------------------------------------------------------------------------- 1 | { 2 | "tileset": { 3 | "resource": "rsrc/tileset.png", 4 | "width": 32, 5 | "height": 32, 6 | "spacing": 0 7 | }, 8 | "tiles": { 9 | "red": [0, 0], 10 | "green": [0, 1], 11 | "blue": [1, 0], 12 | "yellow": [1, 1] 13 | }, 14 | "map": { 15 | "width": 4, 16 | "height": 4, 17 | "tiles": [ 18 | ["green", "green", "yellow", "yellow"], 19 | ["green", "green", "blue", "yellow"], 20 | ["red", "blue", "blue", "blue"], 21 | ["red", "red", "blue", ""] 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /include/sge/nodes/boundingbox.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_BOUDING_BOX_NODE_HPP 2 | #define __SGE_BOUDING_BOX_NODE_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class BoundingBoxNode : public PositionNode 9 | { 10 | using PositionNode::PositionNode; 11 | 12 | public: 13 | virtual std::vector mro() const; 14 | 15 | void set_box(int w, int h); 16 | void set_box(SDL_Point box); 17 | SDL_Point get_box() const; 18 | 19 | private: 20 | SDL_Point size; 21 | }; 22 | } 23 | 24 | #endif /* __SGE_BOUDING_BOX_NODE_HPP */ 25 | -------------------------------------------------------------------------------- /include/sge/initializers/sdl-mixer.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SDL_MIXER_INIT_HPP 2 | #define __SGE_SDL_MIXER_INIT_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class SDLMixerInitializer : public Initializer 9 | { 10 | public: 11 | SDLMixerInitializer(int frequency, int channels, int chunksize); 12 | 13 | void do_initialize(); 14 | void do_shutdown(); 15 | 16 | private: 17 | bool lib_initialized{false}; 18 | int frequency; 19 | int channels; 20 | int chunksize; 21 | }; 22 | } 23 | 24 | #endif /* __SGE_SDL_MIXER_INIT_HPP */ 25 | -------------------------------------------------------------------------------- /include/sge/nodes/collisionshape.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_COLLISION_SHAPE_NODE_HPP 2 | #define __SGE_COLLISION_SHAPE_NODE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class CollisionShapeNode : public PositionNode 10 | { 11 | using PositionNode::PositionNode; 12 | 13 | public: 14 | virtual std::vector mro() const; 15 | 16 | void set_shape(const Shape &shape); 17 | Shape get_shape(); 18 | 19 | private: 20 | Shape _shape; 21 | }; 22 | } 23 | 24 | #endif /* __SGE_COLLISION_SHAPE_NODE_HPP */ 25 | -------------------------------------------------------------------------------- /cmake/FindSDL2.cmake: -------------------------------------------------------------------------------- 1 | # FindSDL2 2 | # -------- 3 | # 4 | # Find SDL2 library, this modules defines: 5 | # 6 | # SDL2_INCLUDE_DIRS, where to find SDL.h 7 | # SDL2_LIBRARIES, where to find library 8 | # SDL2_FOUND, if it is found 9 | 10 | find_path(SDL2_INCLUDE_DIR NAMES SDL.h PATH_SUFFIXES SDL2) 11 | find_library(SDL2_LIBRARY NAMES libSDL2 SDL2) 12 | 13 | include(FindPackageHandleStandardArgs) 14 | 15 | find_package_handle_standard_args( 16 | SDL2 17 | FOUND_VAR SDL2_FOUND 18 | REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR 19 | ) 20 | 21 | set(SDL2_LIBRARIES ${SDL2_LIBRARY}) 22 | set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR}) 23 | 24 | mark_as_advanced(SDL2_INCLUDE_DIR SDL2_LIBRARY) 25 | -------------------------------------------------------------------------------- /src/nodes/boundingbox.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | namespace sge 7 | { 8 | vector BoundingBoxNode::mro() const 9 | { 10 | auto _mro = PositionNode::mro(); 11 | _mro.push_back("BoundingBoxNode"); 12 | return _mro; 13 | } 14 | 15 | void BoundingBoxNode::set_box(int w, int h) 16 | { 17 | size.x = w; 18 | size.y = h; 19 | } 20 | 21 | void BoundingBoxNode::set_box(SDL_Point box) 22 | { 23 | set_box(box.x, box.y); 24 | } 25 | 26 | SDL_Point BoundingBoxNode::get_box() const 27 | { 28 | return size; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /include/sge/nodemgr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_NODE_MANAGER_HPP 2 | #define __SGE_NODE_MANAGER_HPP 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | class NodeManager 9 | { 10 | public: 11 | NodeManager(Engine &engine) : engine(engine) {} 12 | 13 | template 14 | std::shared_ptr create(const std::string &nodename) 15 | { 16 | std::shared_ptr node = std::make_shared(nodename, engine); 17 | node->init(); 18 | return node; 19 | } 20 | 21 | private: 22 | Engine &engine; 23 | 24 | }; 25 | } 26 | 27 | #endif /* __SGE_NODE_MANAGER_HPP */ 28 | -------------------------------------------------------------------------------- /include/sge/assets/loaders/image.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_IMAGE_LOADER_HPP 2 | #define __SGE_IMAGE_LOADER_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace sge 10 | { 11 | class Image : public Asset 12 | { 13 | using Asset::Asset; 14 | }; 15 | 16 | class ImageDescriptor : public AssetDescriptor 17 | { 18 | using AssetDescriptor::AssetDescriptor; 19 | }; 20 | 21 | class ImageLoader : public AssetLoader 22 | { 23 | public: 24 | virtual void load(std::shared_ptr asset, SDL_RWops *input); 25 | virtual void unload(BaseAsset *asset); 26 | }; 27 | } 28 | 29 | #endif /* __SGE_IMAGE_LOADER_HPP */ 30 | -------------------------------------------------------------------------------- /src/nodes/collisionshape.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | namespace sge 7 | { 8 | vector CollisionShapeNode::mro() const 9 | { 10 | auto _mro = PositionNode::mro(); 11 | _mro.push_back("CollisionShapeNode"); 12 | return _mro; 13 | } 14 | 15 | void CollisionShapeNode::set_shape(const Shape &shape) 16 | { 17 | _shape = shape; 18 | } 19 | 20 | Shape CollisionShapeNode::get_shape() 21 | { 22 | Vector abspos(get_absolute_pos()); 23 | Vector barycenter = _shape.barycenter(); 24 | 25 | return _shape.translate(-barycenter).rotate(get_absolute_rotation()).translate(abspos); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/assets/loaders/image.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | namespace sge 6 | { 7 | void ImageLoader::load(shared_ptr asset, SDL_RWops *input) 8 | { 9 | shared_ptr img = static_pointer_cast(asset); 10 | 11 | SDL_Surface *content = IMG_Load_RW(input, 1); 12 | 13 | if (content == nullptr) 14 | { 15 | throw AssetLoaderError("IMG", IMG_GetError()); 16 | } 17 | 18 | img->setAsset(content); 19 | } 20 | 21 | void ImageLoader::unload(BaseAsset *asset) 22 | { 23 | if (asset->loaded()) 24 | { 25 | Image *img = static_cast(asset); 26 | SDL_FreeSurface(img->asset()); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /include/sge/assets/loaders/json.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_JSON_LOADER_HPP 2 | #define __SGE_JSON_LOADER_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace sge 10 | { 11 | class JSON : public Asset 12 | { 13 | using Asset::Asset; 14 | }; 15 | 16 | class JSONDescriptor : public AssetDescriptor 17 | { 18 | public: 19 | JSONDescriptor(const std::string &assetname); 20 | }; 21 | 22 | class JSONLoader : public AssetLoader 23 | { 24 | public: 25 | virtual void load(std::shared_ptr asset, SDL_RWops *input); 26 | virtual void unload(BaseAsset *asset); 27 | }; 28 | } 29 | 30 | #endif /* __SGE_JSON_LOADER_HPP */ 31 | -------------------------------------------------------------------------------- /include/sge/nodes/sprite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SPRITE_NODE_HPP 2 | #define __SGE_SPRITE_NODE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class SpriteNode : public PositionNode 10 | { 11 | using PositionNode::PositionNode; 12 | 13 | public: 14 | virtual std::vector mro() const; 15 | 16 | void set_sprite(const std::string &assetname); 17 | void flip(SDL_RendererFlip flip); 18 | 19 | virtual void ready(); 20 | virtual void draw(); 21 | 22 | private: 23 | std::shared_ptr sprite; 24 | SDL_RendererFlip _flip = SDL_FLIP_NONE; 25 | }; 26 | } 27 | 28 | #endif /* __SGE_SPRITE_NODE_HPP */ 29 | -------------------------------------------------------------------------------- /src/assets/manager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | namespace sge 6 | { 7 | void AssetManager::register_locator(shared_ptr locator) 8 | { 9 | locators.push_back(move(locator)); 10 | } 11 | 12 | void AssetManager::register_loader(shared_ptr loader, const vector &extensions) 13 | { 14 | for (const auto &ext : extensions) 15 | { 16 | loaders[ext] = loader; 17 | } 18 | } 19 | 20 | void AssetManager::unload(BaseAsset *asset) 21 | { 22 | auto it = cache.find(asset->descriptor()); 23 | 24 | if (it != cache.end()) 25 | { 26 | cache.erase(it); 27 | } 28 | 29 | asset->loader()->unload(asset); 30 | delete asset; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /include/sge/nodes/label.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_LABEL_NODE_HPP 2 | #define __SGE_LABEL_NODE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class LabelNode : public PositionNode 10 | { 11 | using PositionNode::PositionNode; 12 | 13 | public: 14 | virtual std::vector mro() const; 15 | 16 | void set_font(const std::string &assetname); 17 | void set_text(const std::string &text); 18 | void set_color(SDL_Color color); 19 | 20 | virtual void ready(); 21 | virtual void draw(); 22 | 23 | private: 24 | std::shared_ptr font; 25 | std::string content; 26 | SDL_Color color; 27 | }; 28 | } 29 | 30 | #endif /* __SGE_LABEL_NODE_HPP */ 31 | -------------------------------------------------------------------------------- /cmake/FindSDL2_ttf.cmake: -------------------------------------------------------------------------------- 1 | # FindSDL2_ttf.cmake 2 | # ------------------ 3 | # 4 | # Find SDL2_ttf library, this modules defines: 5 | # 6 | # SDL2_TTF_INCLUDE_DIRS, where to find SDL_ttf.h 7 | # SDL2_TTF_LIBRARIES, where to find library 8 | # SDL2_TTF_FOUND, if it is found 9 | 10 | find_path( 11 | SDL2_TTF_INCLUDE_DIR 12 | NAMES SDL_ttf.h 13 | PATH_SUFFIXES SDL2 14 | ) 15 | 16 | find_library( 17 | SDL2_TTF_LIBRARY 18 | NAMES libSDL2_ttf SDL2_ttf 19 | ) 20 | 21 | include(FindPackageHandleStandardArgs) 22 | 23 | find_package_handle_standard_args( 24 | SDL2_ttf 25 | FOUND_VAR SDL2_TTF_FOUND 26 | REQUIRED_VARS SDL2_TTF_LIBRARY SDL2_TTF_INCLUDE_DIR 27 | ) 28 | 29 | set(SDL2_TTF_LIBRARIES ${SDL2_TTF_LIBRARY}) 30 | set(SDL2_TTF_INCLUDE_DIRS ${SDL2_TTF_INCLUDE_DIR}) 31 | 32 | mark_as_advanced(SDL2_TTF_INCLUDE_DIR SDL2_TTF_LIBRARY) 33 | -------------------------------------------------------------------------------- /include/sge/assets/cache.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ASSET_CACHE_HPP 2 | #define __SGE_ASSET_CACHE_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace sge 11 | { 12 | struct AssetHasher 13 | { 14 | size_t operator()(std::shared_ptrconst &key) const 15 | { 16 | return key->get_hash(); 17 | } 18 | }; 19 | 20 | struct AssetPred 21 | { 22 | bool operator()(std::shared_ptrconst &a, std::shared_ptrconst &b) const 23 | { 24 | return a->compare(*b); 25 | } 26 | }; 27 | 28 | class AssetCache : public std::unordered_map, std::weak_ptr, AssetHasher, AssetPred> {}; 29 | } 30 | 31 | #endif /* __SGE_ASSET_CACHE_HPP */ 32 | -------------------------------------------------------------------------------- /include/sge/assets/loaders/audio.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_AUDIO_LOADER_HPP 2 | #define __SGE_AUDIO_LOADER_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace sge 10 | { 11 | class Audio : public Asset 12 | { 13 | using Asset::Asset; 14 | 15 | public: 16 | std::shared_ptr music(); 17 | std::shared_ptr effect(); 18 | }; 19 | 20 | class AudioDescriptor : public AssetDescriptor 21 | { 22 | using AssetDescriptor::AssetDescriptor; 23 | }; 24 | 25 | class AudioLoader : public AssetLoader 26 | { 27 | public: 28 | virtual void load(std::shared_ptr asset, SDL_RWops *input); 29 | virtual void unload(BaseAsset *asset); 30 | }; 31 | } 32 | 33 | #endif /* __SGE_AUDIO_LOADER_HPP */ -------------------------------------------------------------------------------- /cmake/FindSDL2_mixer.cmake: -------------------------------------------------------------------------------- 1 | # FindSDL2_mixer.cmake 2 | # -------------------- 3 | # 4 | # Find SDL2_mixer library, this modules defines: 5 | # 6 | # SDL2_MIXER_INCLUDE_DIRS, where to find SDL_mixer.h 7 | # SDL2_MIXER_LIBRARIES, where to find library 8 | # SDL2_MIXER_FOUND, if it is found 9 | 10 | find_path( 11 | SDL2_MIXER_INCLUDE_DIR 12 | NAMES SDL_mixer.h 13 | PATH_SUFFIXES SDL2 14 | ) 15 | 16 | find_library( 17 | SDL2_MIXER_LIBRARY 18 | NAMES libSDL2_mixer SDL2_mixer 19 | ) 20 | 21 | include(FindPackageHandleStandardArgs) 22 | 23 | find_package_handle_standard_args( 24 | SDL2_mixer 25 | FOUND_VAR SDL2_MIXER_FOUND 26 | REQUIRED_VARS SDL2_MIXER_LIBRARY SDL2_MIXER_INCLUDE_DIR 27 | ) 28 | 29 | set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY}) 30 | set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR}) 31 | 32 | mark_as_advanced(SDL2_MIXER_INCLUDE_DIR SDL2_MIXER_LIBRARY) 33 | -------------------------------------------------------------------------------- /include/sge/initializers/sdl-window.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SDL_WINDOW_INIT_HPP 2 | #define __SGE_SDL_WINDOW_INIT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | class SDLWindowInitializer : public Initializer 11 | { 12 | public: 13 | SDLWindowInitializer(int width, int height, bool fullscreen, bool resizable, const std::string &scale); 14 | 15 | void do_initialize(); 16 | void do_shutdown(); 17 | 18 | SDL_Window *window() const; 19 | SDL_Renderer *renderer() const; 20 | 21 | private: 22 | int width; 23 | int height; 24 | bool fullscreen; 25 | bool resizable; 26 | std::string scale; 27 | 28 | SDL_Window *_window; 29 | SDL_Renderer *_renderer; 30 | }; 31 | } 32 | 33 | #endif /* __SGE_SDL_WINDOW_INIT_HPP */ 34 | -------------------------------------------------------------------------------- /cmake/FindSDL2_gfx.cmake: -------------------------------------------------------------------------------- 1 | # FindSDL2_gfx.cmake 2 | # ------------------ 3 | # 4 | # Find SDL2_gfx library, this modules defines: 5 | # 6 | # SDL2_GFX_INCLUDE_DIRS, where to find SDL_gfx.h 7 | # SDL2_GFX_LIBRARIES, where to find library 8 | # SDL2_GFX_FOUND, if it is found 9 | 10 | find_path( 11 | SDL2_GFX_INCLUDE_DIR 12 | NAMES SDL2_gfxPrimitives.h SDL2_rotozoom.h SDL2_framerate.h SDL2_imageFilter.h SDL2_gfxPrimitives_font.h 13 | PATH_SUFFIXES SDL2 14 | ) 15 | 16 | find_library( 17 | SDL2_GFX_LIBRARY 18 | NAMES libSDL2_gfx SDL2_gfx 19 | ) 20 | 21 | include(FindPackageHandleStandardArgs) 22 | 23 | find_package_handle_standard_args( 24 | SDL2_gfx 25 | FOUND_VAR SDL2_GFX_FOUND 26 | REQUIRED_VARS SDL2_GFX_LIBRARY SDL2_GFX_INCLUDE_DIR 27 | ) 28 | 29 | set(SDL2_GFX_LIBRARIES ${SDL2_GFX_LIBRARY}) 30 | set(SDL2_GFX_INCLUDE_DIRS ${SDL2_GFX_INCLUDE_DIR}) 31 | 32 | mark_as_advanced(SDL2_GFX_INCLUDE_DIR SDL2_GFX_LIBRARY) 33 | -------------------------------------------------------------------------------- /include/sge/nodes/tilemap.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_TILEMAP_NODE_HPP 2 | #define __SGE_TILEMAP_NODE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | class TileMapNode : public PositionNode 11 | { 12 | using PositionNode::PositionNode; 13 | 14 | public: 15 | virtual std::vector mro() const; 16 | 17 | void set_tilemap(const std::string &assetname); 18 | 19 | SDL_Rect get_viewport() const; 20 | void set_viewport(SDL_Rect vport); 21 | void set_viewport(int x, int y, int w, int h); 22 | 23 | virtual void ready(); 24 | virtual void draw(); 25 | 26 | private: 27 | std::shared_ptr tileset; 28 | std::shared_ptr tilemap; 29 | SDL_Rect viewport; 30 | }; 31 | } 32 | 33 | #endif /* __SGE_TILEMAP_NODE_HPP */ 34 | -------------------------------------------------------------------------------- /include/sge/config.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_CONFIG_HPP 2 | #define __SGE_CONFIG_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | class Configuration 10 | { 11 | public: 12 | std::string gets(const std::string ¶m, const std::string &_default = std::string()) const; 13 | int geti(const std::string ¶m, int _default = 0) const; 14 | bool getb(const std::string ¶m, bool _default = false) const; 15 | float getf(const std::string ¶m, float _default = 0.0) const; 16 | 17 | Configuration &set(const std::string ¶m, const std::string &value); 18 | Configuration &set(const std::string ¶m, int value); 19 | Configuration &set(const std::string ¶m, bool value); 20 | Configuration &set(const std::string ¶m, float value); 21 | 22 | private: 23 | std::unordered_map kvdb; 24 | }; 25 | } 26 | 27 | #endif /* __SGE_CONFIG_HPP */ -------------------------------------------------------------------------------- /include/sge/nodes/animatedsprite.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ANIMATED_SPRITE_NODE_HPP 2 | #define __SGE_ANIMATED_SPRITE_NODE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | class AnimatedSpriteNode : public PositionNode 11 | { 12 | using PositionNode::PositionNode; 13 | 14 | public: 15 | virtual std::vector mro() const; 16 | 17 | void set_animation(const std::string &assetname); 18 | void flip(SDL_RendererFlip flip); 19 | 20 | virtual void ready(); 21 | virtual void process(Uint32 delta); 22 | virtual void draw(); 23 | 24 | private: 25 | SDL_RendererFlip _flip{SDL_FLIP_NONE}; 26 | int current_frame{0}; 27 | Uint32 elapsed{0}; 28 | std::shared_ptr spritesheet; 29 | std::shared_ptr info; 30 | }; 31 | } 32 | 33 | #endif /* __SGE_ANIMATED_SPRITE_NODE_HPP */ 34 | -------------------------------------------------------------------------------- /include/sge/assets/loaders/font.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_FONT_LOADER_HPP 2 | #define __SGE_FONT_LOADER_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | namespace sge 10 | { 11 | class Font : public Asset 12 | { 13 | using Asset::Asset; 14 | }; 15 | 16 | class FontDescriptor : public AssetDescriptor 17 | { 18 | using AssetDescriptor::AssetDescriptor; 19 | 20 | public: 21 | FontDescriptor(const std::string &assetname, int font_size); 22 | 23 | virtual size_t get_hash() const; 24 | virtual bool compare(const AssetDescriptor &other) const; 25 | 26 | int fontSize() const; 27 | 28 | private: 29 | int font_size; 30 | }; 31 | 32 | class FontLoader : public AssetLoader 33 | { 34 | public: 35 | virtual void load(std::shared_ptr asset, SDL_RWops *input); 36 | virtual void unload(BaseAsset *asset); 37 | }; 38 | } 39 | 40 | #endif /* __SGE_FONT_LOADER_HPP */ 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016-2017 David Delassus 2 | Copyright 2016-2017 David Demelier 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /include/sge/utils/shape.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SHAPE_HPP 2 | #define __SGE_SHAPE_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace sge 8 | { 9 | struct Edge 10 | { 11 | Vector start; 12 | Vector end; 13 | 14 | Edge(Vector s, Vector e) : start(s), end(e) {} 15 | 16 | Vector as_vector() const 17 | { 18 | return end - start; 19 | } 20 | }; 21 | 22 | class Shape 23 | { 24 | public: 25 | Shape(); 26 | Shape(const std::vector &vertices); 27 | 28 | Shape translate(const Vector &v) const; 29 | Vector barycenter() const; 30 | Shape rotate(float angle) const; 31 | std::vector projection(const Vector &v) const; 32 | bool overlap(const Shape &other, Vector &mtv) const; 33 | 34 | std::vector get_edges() const; 35 | 36 | private: 37 | std::vector vertices; 38 | std::vector edges; 39 | }; 40 | } 41 | 42 | #endif /* __SGE_SHAPE_HPP */ 43 | -------------------------------------------------------------------------------- /include/sge/init.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_INIT_HPP 2 | #define __SGE_INIT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | class Initializer 11 | { 12 | public: 13 | Initializer(); 14 | 15 | virtual void do_initialize() = 0; 16 | virtual void do_shutdown() = 0; 17 | 18 | void initialize(); 19 | void shutdown(); 20 | 21 | bool is_initialized() const; 22 | bool is_freed() const; 23 | 24 | private: 25 | bool initialized; 26 | bool freed; 27 | }; 28 | 29 | class InitError : public Exception 30 | { 31 | using Exception::Exception; 32 | }; 33 | 34 | class Startup 35 | { 36 | public: 37 | void add_initializer(std::shared_ptr initializer); 38 | 39 | void initialize(); 40 | void shutdown(); 41 | 42 | private: 43 | std::vector> initializers; 44 | }; 45 | } 46 | 47 | #endif /* __SGE_INIT_HPP */ 48 | -------------------------------------------------------------------------------- /include/sge/actionmgr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_ACTION_MANAGER_HPP 2 | #define __SGE_ACTION_MANAGER_HPP 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | namespace sge 11 | { 12 | class ActionManager 13 | { 14 | public: 15 | void register_keyboard_action(const std::string &name, SDL_Keycode key); 16 | void register_mouse_action(const std::string &name, Uint8 button); 17 | void register_joystick_action(const std::string &name, Uint8 button); 18 | 19 | bool is_action_pressed(const std::string &name); 20 | bool is_action_released(const std::string &name); 21 | 22 | bool event_handler(SDL_Event *event); 23 | 24 | private: 25 | std::unordered_map> a_keyboard; 26 | std::unordered_map> a_mouse; 27 | std::unordered_map> a_joystick; 28 | 29 | std::unordered_map a_active; 30 | }; 31 | } 32 | 33 | #endif /* __SGE_ACTION_MANAGER_HPP */ 34 | -------------------------------------------------------------------------------- /src/initializers/sdl-mixer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | namespace sge 7 | { 8 | const int MIX_INIT_EVERYTHING = MIX_INIT_FLAC | MIX_INIT_MOD | MIX_INIT_MP3 | MIX_INIT_OGG; 9 | 10 | SDLMixerInitializer::SDLMixerInitializer(int frequency, int channels, int chunksize) 11 | : frequency(frequency), channels(channels), chunksize(chunksize) 12 | {} 13 | 14 | void SDLMixerInitializer::do_initialize() 15 | { 16 | 17 | if (Mix_OpenAudio(frequency, MIX_DEFAULT_FORMAT, channels, chunksize) != 0) 18 | { 19 | throw InitError("SDL_mixer", Mix_GetError()); 20 | } 21 | 22 | if ((Mix_Init(MIX_INIT_EVERYTHING) & MIX_INIT_EVERYTHING) != MIX_INIT_EVERYTHING) 23 | { 24 | throw InitError("SDL_mixer", Mix_GetError()); 25 | } 26 | 27 | lib_initialized = true; 28 | } 29 | 30 | void SDLMixerInitializer::do_shutdown() 31 | { 32 | if (lib_initialized) 33 | { 34 | Mix_CloseAudio(); 35 | } 36 | 37 | Mix_Quit(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /include/sge/nodes/canvas.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_CANVAS_HPP 2 | #define __SGE_CANVAS_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace sge 11 | { 12 | using CanvasDrawRequest = std::function; 13 | 14 | class CanvasNode : public PositionNode 15 | { 16 | using PositionNode::PositionNode; 17 | 18 | public: 19 | virtual std::vector mro() const; 20 | 21 | virtual void ready(); 22 | virtual void draw(); 23 | 24 | void clear(); 25 | void draw_point(Vector pos, SDL_Color color); 26 | void draw_line(Vector start, Vector end, SDL_Color color); 27 | void draw_rect(SDL_Rect rect, SDL_Color color); 28 | void draw_filled_rect(SDL_Rect rect, SDL_Color color); 29 | void draw_shape(const Shape &shape, SDL_Color color); 30 | void draw_filled_shape(const Shape &shape, SDL_Color color); 31 | 32 | private: 33 | std::vector requests; 34 | }; 35 | } 36 | 37 | #endif /* __SGE_CANVAS_HPP */ 38 | -------------------------------------------------------------------------------- /include/sge/scenemgr.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_SCENE_MANAGER_HPP 2 | #define __SGE_SCENE_MANAGER_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace sge 12 | { 13 | class Scene 14 | { 15 | public: 16 | Scene(); 17 | 18 | virtual void load(Engine &engine) = 0; 19 | virtual void unload(Engine &engine) = 0; 20 | 21 | std::shared_ptr get_root_node() const; 22 | 23 | protected: 24 | std::shared_ptr root_node; 25 | }; 26 | 27 | class SceneManager 28 | { 29 | public: 30 | SceneManager(Engine &engine); 31 | ~SceneManager(); 32 | 33 | void add_scene(const std::string &name, std::shared_ptr scene); 34 | void switch_to_scene(const std::string &name); 35 | 36 | std::shared_ptr get_scene_node(); 37 | 38 | bool event_handler(SDL_Event *event); 39 | void process_handler(Uint32 delta); 40 | void draw_handler(); 41 | 42 | private: 43 | Engine &engine; 44 | std::shared_ptr current_scene; 45 | 46 | std::unordered_map> scenes; 47 | }; 48 | } 49 | 50 | #endif /* __SGE_SCENE_MANAGER_HPP */ 51 | -------------------------------------------------------------------------------- /include/sge/nodes/position.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_POSITION_NODE_HPP 2 | #define __SGE_POSITION_NODE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sge 9 | { 10 | class PositionNode : public Node 11 | { 12 | using Node::Node; 13 | 14 | public: 15 | virtual std::vector mro() const; 16 | 17 | Vector get_pos() const; 18 | void set_pos(const Vector &pos); 19 | void set_pos(int x, int y); 20 | 21 | float get_rotation() const; 22 | void set_rotation(float angle); 23 | 24 | float get_zoom() const; 25 | void set_zoom(float zoom); 26 | 27 | Vector get_absolute_pos(); 28 | float get_absolute_rotation() const; 29 | float get_absolute_zoom() const; 30 | 31 | Matrix<3,3> get_pm_transform() const; 32 | 33 | private: 34 | void premultiply_pos(); 35 | 36 | private: 37 | Vector _pos; 38 | float _angle = 0; 39 | float _zoom = 0; 40 | 41 | Matrix<3,3> translation; 42 | Matrix<3,3> rotation; 43 | Matrix<3,3> local_pm_transform; 44 | Matrix<3,3> parent_pm_transform; 45 | Vector pm_pos; 46 | }; 47 | } 48 | 49 | #endif /* __SGE_POSITION_NODE_HPP */ 50 | -------------------------------------------------------------------------------- /src/nodes/label.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | namespace sge 8 | { 9 | vector LabelNode::mro() const 10 | { 11 | auto _mro = PositionNode::mro(); 12 | _mro.push_back("LabelNode"); 13 | return _mro; 14 | } 15 | 16 | void LabelNode::set_font(const string &assetname) 17 | { 18 | FontDescriptor d(assetname); 19 | 20 | if (font == nullptr) 21 | { 22 | font = engine.assets().load(d); 23 | } 24 | else if (font->descriptor()->name() != d.name()) 25 | { 26 | font.reset(); 27 | font = engine.assets().load(d); 28 | } 29 | } 30 | 31 | void LabelNode::set_text(const string &text) 32 | { 33 | content = text; 34 | } 35 | 36 | void LabelNode::set_color(SDL_Color fg) 37 | { 38 | color = fg; 39 | } 40 | 41 | void LabelNode::ready() 42 | { 43 | set_draw(true); 44 | } 45 | 46 | void LabelNode::draw() 47 | { 48 | if (font == nullptr || content.empty()) 49 | { 50 | return; 51 | } 52 | 53 | if (!engine.renderer().draw_text(font, content, get_absolute_pos(), color)) 54 | { 55 | cerr << "[LabelNode][ERROR] " << engine.renderer().get_error() << endl; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/assets/locators/file.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | namespace sge 10 | { 11 | #ifdef _WIN32 12 | const char SEPARATOR = '\\'; 13 | const char REPLACE = '/'; 14 | #else 15 | const char SEPARATOR = '/'; 16 | const char REPLACE = '\\'; 17 | #endif 18 | 19 | FileLocator::FileLocator(const string &location) : AssetLocator() 20 | { 21 | if (location.empty()) 22 | { 23 | char *tmp = SDL_GetBasePath(); 24 | 25 | if (tmp == nullptr) 26 | { 27 | _location = "."; 28 | } 29 | else 30 | { 31 | _location = tmp; 32 | _location = _location.substr(0, _location.length() - 1); 33 | } 34 | } 35 | else 36 | { 37 | _location = location; 38 | } 39 | } 40 | 41 | SDL_RWops *FileLocator::locate(const string &assetname, bool binary) 42 | { 43 | string fullpath = _location + SEPARATOR + assetname; 44 | replace(fullpath.begin(), fullpath.end(), REPLACE, SEPARATOR); 45 | 46 | SDL_RWops *input = SDL_RWFromFile(fullpath.c_str(), (binary ? "rb" : "r")); 47 | 48 | if (input == nullptr) 49 | { 50 | throw AssetLocatorError("SDL", SDL_GetError()); 51 | } 52 | 53 | return input; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/assets/loaders/json.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace nlohmann; 7 | using namespace std; 8 | 9 | namespace sge 10 | { 11 | JSONDescriptor::JSONDescriptor(const string &assetname) : AssetDescriptor(assetname, false) {} 12 | 13 | void JSONLoader::load(shared_ptr asset, SDL_RWops *input) 14 | { 15 | shared_ptr jdoc = static_pointer_cast(asset); 16 | 17 | Sint64 length = SDL_RWseek(input, 0, RW_SEEK_END); 18 | 19 | if (length < 0) 20 | { 21 | throw AssetLoaderError("SDL", "Cannot seek into stream"); 22 | } 23 | 24 | SDL_RWseek(input, 0, RW_SEEK_SET); 25 | 26 | char *buffer = new char[length]; 27 | memset(buffer, 0, length); 28 | 29 | SDL_RWread(input, buffer, sizeof(char), length); 30 | json j; 31 | 32 | try 33 | { 34 | j = json::parse(buffer); 35 | } 36 | catch(const exception &e) 37 | { 38 | delete[] buffer; 39 | throw AssetLoaderError("JSON", e.what()); 40 | } 41 | 42 | delete[] buffer; 43 | jdoc->setAsset(j); 44 | 45 | if (SDL_RWclose(input) != 0) 46 | { 47 | cerr << "[JSONLoader] [WARNING] " << SDL_GetError() << endl; 48 | } 49 | } 50 | 51 | void JSONLoader::unload(BaseAsset *) 52 | { 53 | ; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/assets/loaders/font.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | namespace sge 6 | { 7 | FontDescriptor::FontDescriptor(const string &assetname, int font_size) : AssetDescriptor(assetname), font_size(font_size) {} 8 | 9 | size_t FontDescriptor::get_hash() const 10 | { 11 | hash hashfn; 12 | return AssetDescriptor::get_hash() ^ hashfn(font_size); 13 | } 14 | 15 | bool FontDescriptor::compare(const AssetDescriptor &other) const 16 | { 17 | auto descriptor = static_cast(other); 18 | return AssetDescriptor::compare(other) && (font_size == descriptor.fontSize()); 19 | } 20 | 21 | int FontDescriptor::fontSize() const 22 | { 23 | return font_size; 24 | } 25 | 26 | void FontLoader::load(shared_ptr asset, SDL_RWops *input) 27 | { 28 | shared_ptr font = static_pointer_cast(asset); 29 | auto descriptor = static_pointer_cast(font->descriptor()); 30 | 31 | TTF_Font *content = TTF_OpenFontRW(input, 1, descriptor->fontSize()); 32 | 33 | if (content == nullptr) 34 | { 35 | throw AssetLoaderError("TTF", TTF_GetError()); 36 | } 37 | 38 | font->setAsset(content); 39 | } 40 | 41 | void FontLoader::unload(BaseAsset *asset) 42 | { 43 | if (asset->loaded()) 44 | { 45 | Font *font = static_cast(asset); 46 | TTF_CloseFont(font->asset()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/init.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace sge 4 | { 5 | Initializer::Initializer() : initialized(false), freed(false) 6 | {} 7 | 8 | void Initializer::initialize() 9 | { 10 | if (!initialized) 11 | { 12 | do_initialize(); 13 | initialized = true; 14 | } 15 | } 16 | 17 | void Initializer::shutdown() 18 | { 19 | if (!freed) 20 | { 21 | do_shutdown(); 22 | freed = true; 23 | } 24 | } 25 | 26 | bool Initializer::is_initialized() const 27 | { 28 | return initialized; 29 | } 30 | 31 | bool Initializer::is_freed() const 32 | { 33 | return freed; 34 | } 35 | 36 | void Startup::add_initializer(std::shared_ptr initializer) 37 | { 38 | initializers.push_back(std::move(initializer)); 39 | } 40 | 41 | void Startup::initialize() 42 | { 43 | for (auto it = initializers.begin(); it != initializers.end(); it++) 44 | { 45 | auto initializer = *it; 46 | 47 | if (!initializer->is_initialized()) 48 | { 49 | initializer->initialize(); 50 | } 51 | } 52 | } 53 | 54 | void Startup::shutdown() 55 | { 56 | for (auto it = initializers.rbegin(); it != initializers.rend(); it++) 57 | { 58 | auto initializer = *it; 59 | 60 | if (initializer->is_initialized() && !initializer->is_freed()) 61 | { 62 | initializer->shutdown(); 63 | } 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/initializers/sdl-window.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | namespace sge 6 | { 7 | SDLWindowInitializer::SDLWindowInitializer(int width, int height, bool fullscreen, bool resizable, const string &scale) 8 | : width(width), height(height), 9 | fullscreen(fullscreen), resizable(resizable), scale(scale), 10 | _window(nullptr), _renderer(nullptr) 11 | {} 12 | 13 | void SDLWindowInitializer::do_initialize() 14 | { 15 | Uint32 flags = 0; 16 | 17 | if (fullscreen) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; 18 | if (resizable) flags |= SDL_WINDOW_RESIZABLE; 19 | 20 | if (SDL_CreateWindowAndRenderer(width, height, flags, &_window, &_renderer) != 0) 21 | { 22 | throw InitError("SDL", SDL_GetError()); 23 | } 24 | 25 | if (!scale.empty() && scale != "none") 26 | { 27 | SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, scale.c_str()); 28 | SDL_RenderSetLogicalSize(_renderer, width, height); 29 | } 30 | } 31 | 32 | void SDLWindowInitializer::do_shutdown() 33 | { 34 | if (_renderer != nullptr) 35 | { 36 | SDL_DestroyRenderer(_renderer); 37 | } 38 | 39 | if (_window != nullptr) 40 | { 41 | SDL_DestroyWindow(_window); 42 | } 43 | } 44 | 45 | SDL_Window *SDLWindowInitializer::window() const 46 | { 47 | return _window; 48 | } 49 | 50 | SDL_Renderer *SDLWindowInitializer::renderer() const 51 | { 52 | return _renderer; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /include/sge/mainloop.hpp: -------------------------------------------------------------------------------- 1 | #ifndef __SGE_MAINLOOP_HPP 2 | #define __SGE_MAINLOOP_HPP 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace sge 13 | { 14 | using EventHandler = std::function; 15 | using ProcessHandler = std::function; 16 | using DrawHandler = std::function; 17 | 18 | using ProcessEntry = std::tuple; 19 | 20 | class MainLoop 21 | { 22 | public: 23 | MainLoop(int fps); 24 | 25 | void add_event_watcher(EventHandler handler); 26 | void remove_event_watcher(EventHandler handler); 27 | 28 | void queue_event_handler(Uint32 evtype, EventHandler handler); 29 | void dequeue_event_handler(Uint32 evtype, EventHandler handler); 30 | 31 | void queue_process_handler(ProcessHandler handler); 32 | void dequeue_process_handler(ProcessHandler handler); 33 | 34 | void queue_draw_handler(DrawHandler handler); 35 | void dequeue_draw_handler(DrawHandler handler); 36 | 37 | void run(); 38 | void quit(); 39 | 40 | private: 41 | int fps; 42 | bool running; 43 | Timer fps_timer; 44 | 45 | std::list evtwatchers; 46 | std::unordered_map> events; 47 | std::list processing; 48 | std::list drawing; 49 | }; 50 | } 51 | 52 | #endif /* __SGE_MAINLOOP_HPP */ 53 | -------------------------------------------------------------------------------- /src/assets/asset.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | namespace sge 7 | { 8 | AssetDescriptor::AssetDescriptor(const string &assetname, bool binary) : assetname(assetname), _binary(binary) {} 9 | 10 | size_t AssetDescriptor::get_hash() const 11 | { 12 | hash hashfn; 13 | return hashfn(assetname); 14 | } 15 | 16 | bool AssetDescriptor::compare(const AssetDescriptor &other) const 17 | { 18 | return (assetname == other.name()); 19 | } 20 | 21 | const string &AssetDescriptor::name() const 22 | { 23 | return assetname; 24 | } 25 | 26 | bool AssetDescriptor::binary() const 27 | { 28 | return _binary; 29 | } 30 | 31 | string AssetDescriptor::extension() const 32 | { 33 | size_t found = assetname.rfind("."); 34 | string result(""); 35 | 36 | if (found != string::npos) 37 | { 38 | result = assetname.substr(found + 1); 39 | } 40 | 41 | return result; 42 | } 43 | 44 | BaseAsset::BaseAsset(shared_ptr loader, shared_ptr assetdesc) 45 | : _loader(loader), desc(assetdesc), _loaded(false) 46 | {} 47 | 48 | shared_ptr BaseAsset::loader() 49 | { 50 | return _loader; 51 | } 52 | 53 | void BaseAsset::setLoaded() 54 | { 55 | _loaded = true; 56 | } 57 | 58 | bool BaseAsset::loaded() const 59 | { 60 | return _loaded; 61 | } 62 | 63 | shared_ptr BaseAsset::descriptor() 64 | { 65 | return desc; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/nodes/sprite.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | namespace sge 8 | { 9 | vector SpriteNode::mro() const 10 | { 11 | auto _mro = PositionNode::mro(); 12 | _mro.push_back("SpriteNode"); 13 | return _mro; 14 | } 15 | 16 | void SpriteNode::set_sprite(const string &assetname) 17 | { 18 | ImageDescriptor d(assetname); 19 | 20 | if (sprite == nullptr) 21 | { 22 | sprite = engine.assets().load(d); 23 | } 24 | else if (sprite->descriptor()->name() != d.name()) 25 | { 26 | sprite.reset(); 27 | sprite = engine.assets().load(d); 28 | } 29 | } 30 | 31 | void SpriteNode::flip(SDL_RendererFlip flip) 32 | { 33 | _flip = (SDL_RendererFlip) (_flip | flip); 34 | } 35 | 36 | void SpriteNode::ready() 37 | { 38 | set_draw(true); 39 | } 40 | 41 | void SpriteNode::draw() 42 | { 43 | if (sprite == nullptr) 44 | { 45 | return; 46 | } 47 | 48 | SDL_Point pos = get_absolute_pos().as_point(); 49 | int angle = get_absolute_rotation(); 50 | SDL_Rect dest; 51 | 52 | int w = sprite->asset()->w; 53 | int h = sprite->asset()->h; 54 | 55 | dest.x = pos.x - w / 2; 56 | dest.y = pos.y - h / 2; 57 | dest.w = w; 58 | dest.h = h; 59 | 60 | if (!engine.renderer().draw_image(sprite, dest, angle, pos, _flip)) 61 | { 62 | cerr << "[SpriteNode][ERROR] " << engine.renderer().get_error() << endl; 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/assets/loaders/audio.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | namespace sge 7 | { 8 | shared_ptr Audio::music() 9 | { 10 | if (loaded()) 11 | { 12 | SDL_RWops *audiodata = asset(); 13 | auto music = Mix_LoadMUS_RW(audiodata, 0); 14 | 15 | if (music != nullptr) 16 | { 17 | return shared_ptr(music, Mix_FreeMusic); 18 | } 19 | else 20 | { 21 | cerr << "[Audio][ERROR] SDL_Mixer: " << Mix_GetError() << endl; 22 | } 23 | } 24 | 25 | return nullptr; 26 | } 27 | 28 | shared_ptr Audio::effect() 29 | { 30 | if (loaded()) 31 | { 32 | SDL_RWops *audiodata = asset(); 33 | auto effect = Mix_LoadWAV_RW(audiodata, 0); 34 | 35 | if (effect != nullptr) 36 | { 37 | return shared_ptr(effect, Mix_FreeChunk); 38 | } 39 | else 40 | { 41 | cerr << "[Audio][ERROR] SDL_Mixer: " << Mix_GetError() << endl; 42 | } 43 | 44 | } 45 | 46 | return nullptr; 47 | } 48 | 49 | void AudioLoader::load(shared_ptr asset, SDL_RWops *input) 50 | { 51 | shared_ptr