Browse code

start scenimp scenegraph project

devnewton authored on 06/09/2015 22:02:01
Showing 28 changed files
... ...
@@ -26,5 +26,15 @@ include_directories(${SDL2_MIXER_INCLUDE_DIR})
26 26
 find_package(SDL2_ttf REQUIRED)
27 27
 include_directories(${SDL2_TTF_INCLUDE_DIR})
28 28
 
29
-add_executable(superpaflaballe src/assets.cpp src/bourrines_benchmark.cpp src/framerate.cpp src/game.cpp src/intro.cpp src/main.cpp src/nanim.cpp src/sdl_exception.cpp)
29
+add_executable(superpaflaballe
30
+ src/bourrines_benchmark.cpp
31
+ src/scenimp/assets.cpp
32
+ src/scenimp/game.cpp
33
+ src/scenimp/group.cpp
34
+ src/scenimp/nanim.cpp
35
+ src/scenimp/node.cpp
36
+ src/scenimp/sdl_exception.cpp
37
+ src/framerate.cpp
38
+ src/intro.cpp
39
+ src/main.cpp)
30 40
 target_link_libraries(superpaflaballe ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY} ${SDL2_MIXER_LIBRARY} ${SDL2_TTF_LIBRARY} ${Boost_LIBRARIES})
31 41
deleted file mode 100644
... ...
@@ -1,160 +0,0 @@
1
-#include "assets.h"
2
-#include "game.h"
3
-#include "sdl_exception.h"
4
-#include <SDL_image.h>
5
-#include <boost/property_tree/ptree.hpp>
6
-#include <boost/property_tree/json_parser.hpp>
7
-#include <boost/filesystem/path.hpp>
8
-#include <boost/filesystem/operations.hpp>
9
-
10
-namespace superpaflaballe {
11
-
12
-    assets::assets(game& game)
13
-    : game_(game) {
14
-        pathPrefixes_.push_back("../assets/");
15
-        pathPrefixes_.push_back(PREFIX "/games/superpaflaballe/");
16
-        if (TTF_Init() != 0) {
17
-            throw sdl_exception();
18
-        }
19
-        const int img_flags = IMG_INIT_PNG;
20
-        int img_initted = IMG_Init(img_flags);
21
-        if ((img_initted & img_flags) != img_flags) {
22
-            throw sdl_exception();
23
-        }
24
-        int mix_flags = MIX_INIT_OGG;
25
-        int mix_initted = Mix_Init(mix_flags);
26
-        if ((mix_initted & mix_flags) != mix_flags) {
27
-            throw sdl_exception();
28
-        }
29
-       if( Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT , 2, 1024) != 0 ) {
30
-            throw sdl_exception();
31
-        }
32
-    }
33
-
34
-    assets::~assets() {
35
-        Mix_CloseAudio();
36
-        Mix_Quit();
37
-        IMG_Quit();
38
-        TTF_Quit();
39
-    }
40
-
41
-    std::shared_ptr< TTF_Font > assets::font(const std::string& path, int size) {
42
-        auto key = std::make_pair(path, size);
43
-        auto font = fonts_[key].lock();
44
-        if (font) {
45
-            return font;
46
-        }
47
-        boost::filesystem::path fspath(path);
48
-        for (auto& prefix : pathPrefixes_) {
49
-            boost::filesystem::path fsprefix(prefix);
50
-            font = load_font((fsprefix / fspath).string(), size);
51
-            if (font) {
52
-                fonts_[key] = font;
53
-                return font;
54
-            }
55
-        }
56
-        throw std::runtime_error("Cannot load font " + path);
57
-    }
58
-
59
-    std::shared_ptr< TTF_Font > assets::load_font(const std::string path, int size) {
60
-        return std::shared_ptr< TTF_Font >(TTF_OpenFont(path.c_str(), size), TTF_CloseFont);
61
-    }
62
-
63
-    std::shared_ptr< Mix_Music > assets::music(const std::string& path) {
64
-        auto music = musics_[path].lock();
65
-        if (music) {
66
-            return music;
67
-        }
68
-        boost::filesystem::path fspath(path);
69
-        for (auto& prefix : pathPrefixes_) {
70
-            boost::filesystem::path fsprefix(prefix);
71
-            music = load_music((fsprefix / fspath).string());
72
-            if (music) {
73
-                musics_[path] = music;
74
-                return music;
75
-            }
76
-        }
77
-        throw std::runtime_error("Cannot load music " + path);
78
-    }
79
-
80
-     std::shared_ptr< Mix_Music > assets::load_music(const std::string& path) {
81
-        return std::shared_ptr< Mix_Music >(Mix_LoadMUS(path.c_str()), Mix_FreeMusic);
82
-    }
83
-
84
-    std::shared_ptr< SDL_Texture > assets::texture(const std::string& path) {
85
-        auto texture = textures_[path].lock();
86
-        if (texture) {
87
-            return texture;
88
-        }
89
-        boost::filesystem::path fspath(path);
90
-        for (auto& prefix : pathPrefixes_) {
91
-            boost::filesystem::path fsprefix(prefix);
92
-            texture = load_texture((fsprefix / fspath).string());
93
-            if (texture) {
94
-                textures_[path] = texture;
95
-                return texture;
96
-            }
97
-        }
98
-        throw std::runtime_error("Cannot load texture " + path);
99
-    }
100
-
101
-    std::shared_ptr< SDL_Texture > assets::load_texture(const std::string path) {
102
-        return std::shared_ptr< SDL_Texture >(IMG_LoadTexture(game_.renderer(), path.c_str()), SDL_DestroyTexture);
103
-    }
104
-
105
-    std::shared_ptr< nanim::collection > assets::animations(const std::string& path) {
106
-        auto animations = animations_[path].lock();
107
-        if (animations) {
108
-            return animations;
109
-        }
110
-        for (auto& prefix : pathPrefixes_) {
111
-            try {
112
-                animations = load_json_nanim(prefix + path);
113
-                if (animations) {
114
-                    animations_[path] = animations;
115
-                    return animations;
116
-                }
117
-            } catch (...) {
118
-            }
119
-        }
120
-        throw std::runtime_error("Cannot load animations " + path);
121
-    }
122
-
123
-    std::shared_ptr<nanim::collection> assets::load_json_nanim(const std::string& path) {
124
-        using boost::property_tree::ptree;
125
-        if (!boost::filesystem::exists(path)) {
126
-            return nullptr;
127
-        }
128
-        ptree pt_nanim;
129
-        boost::property_tree::read_json(path, pt_nanim);
130
-        boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path();
131
-        auto collec = std::make_shared<nanim::collection>();
132
-
133
-        for (auto& pt_animation : pt_nanim.get_child("animations")) {
134
-            auto anim = std::make_shared<nanim::animation>();
135
-            for (auto& pt_frame_child : pt_animation.second.get_child("frames")) {
136
-                auto pt_frame = pt_frame_child.second;
137
-                nanim::frame fram;
138
-                fram.duration_ = pt_frame.get<long>("duration");
139
-                anim->total_duration_ += fram.duration_;
140
-                fram.end_time_ = anim->total_duration_;
141
-                float u1 = pt_frame.get<float>("u1");
142
-                float v1 = pt_frame.get<float>("v1");
143
-                float u2 = pt_frame.get<float>("u2");
144
-                float v2 = pt_frame.get<float>("v2");
145
-                fram.image_ = load_texture((parent_path / pt_frame.get<std::string>("image")).string());
146
-                int w, h;
147
-                SDL_QueryTexture(fram.image_.get(), NULL, NULL, &w, &h);
148
-                fram.rect_.x = u1 * w;
149
-                fram.rect_.y = v1 * w;
150
-                fram.rect_.w = (u2 - u1) * w;
151
-                fram.rect_.h = (v2 - v1) * h;
152
-                anim->frames_.push_back(fram);
153
-            }
154
-            std::string name = pt_animation.second.get<std::string>("name");
155
-            collec->animations_[name] = anim;
156
-        }
157
-        return collec;
158
-    }
159
-
160
-}
161 0
deleted file mode 100644
... ...
@@ -1,36 +0,0 @@
1
-#pragma once
2
-
3
-#include "nanim.h"
4
-#include <SDL_mixer.h>
5
-#include <SDL_ttf.h>
6
-
7
-namespace superpaflaballe {
8
-
9
-    class game;
10
-
11
-    class assets {
12
-    public:
13
-        assets(game& game);
14
-        ~assets();
15
-
16
-        std::shared_ptr< nanim::collection > animations(const std::string& path);
17
-        std::shared_ptr< TTF_Font > font(const std::string& path, int size);
18
-        std::shared_ptr< Mix_Music > music(const std::string& path);
19
-        std::shared_ptr< SDL_Texture > texture(const std::string& path);
20
-
21
-
22
-    private:
23
-        std::shared_ptr< TTF_Font > load_font(const std::string path, int size);
24
-        std::shared_ptr<nanim::collection> load_json_nanim(const std::string& path);
25
-        std::shared_ptr< Mix_Music > load_music(const std::string& path);
26
-        std::shared_ptr< SDL_Texture > load_texture(const std::string path);
27
-
28
-        game& game_;
29
-        std::vector<std::string> pathPrefixes_;
30
-        std::map<std::string, std::weak_ptr< nanim::collection > > animations_;
31
-        std::map<std::pair<std::string, int/*font size*/>, std::weak_ptr< TTF_Font > > fonts_;
32
-        std::map<std::string, std::weak_ptr< SDL_Texture > > textures_;
33
-        std::map<std::string, std::weak_ptr< Mix_Music > > musics_;
34
-    };
35
-
36
-}
... ...
@@ -71,11 +71,11 @@ namespace superpaflaballe {
71 71
                 dir.dy_ = -dir.dy_;
72 72
             }
73 73
 
74
-            if (pos.x_ >= logical_screen_width) {
74
+            if (pos.x_ >= scenimp::logical_screen_width) {
75 75
                 dir.dx_ = -dir.dx_;
76 76
             }
77 77
 
78
-            if (pos.y_ >= logical_screen_height) {
78
+            if (pos.y_ >= scenimp::logical_screen_height) {
79 79
                 dir.dy_ = -dir.dy_;
80 80
             }
81 81
         }
... ...
@@ -85,7 +85,7 @@ namespace superpaflaballe {
85 85
     class render_system : public bourrines::selective_processing_system<world> {
86 86
     public:
87 87
 
88
-        render_system(game& g)
88
+        render_system(scenimp::game& g)
89 89
         : game_(g) {
90 90
         }
91 91
 
... ...
@@ -104,10 +104,10 @@ namespace superpaflaballe {
104 104
             SDL_RenderCopy(game_.renderer(), anim.play_->current_frame().image().get(), &anim.play_->current_frame().rect(), &rect);
105 105
         }
106 106
     private:
107
-        game& game_;
107
+        scenimp::game& game_;
108 108
     };
109 109
 
110
-    bourrines_benchmark::bourrines_benchmark(game& ga, int num_entity, int num_ticks)
110
+    bourrines_benchmark::bourrines_benchmark(scenimp::game& ga, int num_entity, int num_ticks)
111 111
     : remaining_ticks_(num_ticks) {
112 112
         timer_.stop();
113 113
         ned_anim_ = ga.assets().animations("ned.json");
... ...
@@ -124,14 +124,14 @@ namespace superpaflaballe {
124 124
     void bourrines_benchmark::create_ned() {
125 125
         bourrines::entity e = world_.create_entity();
126 126
         pos_component& pos = world_.add<pos_component>(e);
127
-        pos.x_ = std::rand() % logical_screen_width;
128
-        pos.y_ = std::rand() % logical_screen_height;
127
+        pos.x_ = std::rand() % scenimp::logical_screen_width;
128
+        pos.y_ = std::rand() % scenimp::logical_screen_height;
129 129
 
130 130
         dir_component& dir = world_.add<dir_component>(e);
131 131
         dir.dx_ = (1 + (std::rand() % 10)) * ((std::rand() % 1) ? -1 : 1);
132 132
         dir.dy_ = (1 + (std::rand() % 10)) * ((std::rand() % 1) ? -1 : 1);
133 133
 
134
-        world_.add<anim_component>(e).play_ = ned_anim_->play(superpaflaballe::nanim::loop);
134
+        world_.add<anim_component>(e).play_ = ned_anim_->play(scenimp::nanim::loop);
135 135
         world_.add<life_component>(e).life_ = remaining_ticks_ > 0 ? std::rand() % remaining_ticks_ : 1;
136 136
 
137 137
         world_.changed(e);
... ...
@@ -1,8 +1,8 @@
1 1
 #pragma once
2 2
 
3
-#include "game.h"
4
-#include "nanim.h"
5
-#include "assets.h"
3
+#include "scenimp/game.h"
4
+#include "scenimp/nanim.h"
5
+#include "scenimp/assets.h"
6 6
 #include "bourrines/bourrines.h"
7 7
 
8 8
 #include <boost/timer/timer.hpp>
... ...
@@ -22,14 +22,14 @@ namespace superpaflaballe {
22 22
     };
23 23
 
24 24
     struct anim_component {
25
-        std::shared_ptr< nanim::play > play_;
25
+        std::shared_ptr< scenimp::nanim::play > play_;
26 26
     };
27 27
 
28 28
     typedef bourrines::default_world<pos_component, dir_component, life_component, anim_component> world;
29 29
 
30 30
     class bourrines_benchmark {
31 31
     public:
32
-        bourrines_benchmark(game& g, int num_entity, int num_ticks);
32
+        bourrines_benchmark(scenimp::game& g, int num_entity, int num_ticks);
33 33
         ~bourrines_benchmark();
34 34
         
35 35
         void tick();
... ...
@@ -39,7 +39,7 @@ namespace superpaflaballe {
39 39
         
40 40
     private:
41 41
         world world_;
42
-        std::shared_ptr< nanim::collection > ned_anim_;
42
+        std::shared_ptr< scenimp::nanim::collection > ned_anim_;
43 43
         boost::timer::auto_cpu_timer timer_;
44 44
         int remaining_ticks_;
45 45
     };
46 46
deleted file mode 100644
... ...
@@ -1,51 +0,0 @@
1
-#include "game.h"
2
-#include "sdl_exception.h"
3
-
4
-#include <SDL.h>
5
-
6
-namespace superpaflaballe {
7
-
8
-    game::game() {
9
-        if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
10
-            throw sdl_exception();
11
-        }
12
-        window_ = SDL_CreateWindow("superpaflaballe", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 360, SDL_WINDOW_RESIZABLE);
13
-        if (!window_) {
14
-            SDL_Quit();
15
-            throw sdl_exception();
16
-        }
17
-        renderer_ = SDL_CreateRenderer(window_, -1, 0);
18
-        if (!renderer_) {
19
-            SDL_DestroyWindow(window_);
20
-            SDL_Quit();
21
-            throw sdl_exception();
22
-        }
23
-        SDL_RenderSetLogicalSize(renderer_, logical_screen_width, logical_screen_height);
24
-        assets_ = new superpaflaballe::assets(*this);
25
-    }
26
-
27
-    game::~game() {
28
-        delete assets_;
29
-        SDL_DestroyRenderer(renderer_);
30
-        SDL_DestroyWindow(window_);
31
-        SDL_Quit();
32
-    }
33
-
34
-    SDL_Window* game::window() {
35
-        return window_;
36
-    }
37
-
38
-    SDL_Renderer* game::renderer() {
39
-        return renderer_;
40
-    }
41
-
42
-    assets& game::assets() {
43
-        return *assets_;
44
-    }
45
-
46
-    std::shared_ptr< SDL_Texture > game::create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color) {
47
-        std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *) > text_surface(TTF_RenderText_Blended(font.get(), str.c_str(), color), SDL_FreeSurface);
48
-        return std::shared_ptr< SDL_Texture >(SDL_CreateTextureFromSurface(renderer(), text_surface.get()), SDL_DestroyTexture);
49
-    }
50
-
51
-}
52 0
deleted file mode 100644
... ...
@@ -1,28 +0,0 @@
1
-#pragma once
2
-
3
-#include "assets.h"
4
-
5
-namespace superpaflaballe {
6
-
7
-    const int logical_screen_width = 1920;
8
-    const int logical_screen_height = 1080;
9
-
10
-    class game {
11
-    public:
12
-        game();
13
-        ~game();
14
-
15
-        SDL_Window* window();
16
-        SDL_Renderer* renderer();
17
-        superpaflaballe::assets& assets();
18
-
19
-        std::shared_ptr< SDL_Texture > create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color = {255, 255, 255, 0});
20
-
21
-    private:
22
-        superpaflaballe::assets* assets_;
23
-        SDL_Window* window_;
24
-        SDL_Renderer* renderer_;
25
-    };
26
-
27
-}
28
-
... ...
@@ -7,9 +7,9 @@
7 7
 
8 8
 namespace superpaflaballe {
9 9
 
10
-    intro::intro(game& ga)
10
+    intro::intro(scenimp::game& ga)
11 11
     : game_(ga)
12
-    , play_(ga.assets().animations("intro/devnewton.json")->play(superpaflaballe::nanim::once))
12
+    , play_(ga.assets().animations("intro/devnewton.json")->play(scenimp::nanim::once))
13 13
     , music_(ga.assets().music("intro/devnewton.ogg")) {
14 14
         Mix_PlayMusic(music_.get(), 1);
15 15
     }
... ...
@@ -23,8 +23,8 @@ namespace superpaflaballe {
23 23
         SDL_Rect rect;
24 24
         rect.w = 512;
25 25
         rect.h = 116;
26
-        rect.x = (superpaflaballe::logical_screen_width - rect.w) / 2;
27
-        rect.y = (superpaflaballe::logical_screen_height - rect.h) / 2;
26
+        rect.x = (scenimp::logical_screen_width - rect.w) / 2;
27
+        rect.y = (scenimp::logical_screen_height - rect.h) / 2;
28 28
         SDL_RenderCopy(game_.renderer(), play_->current_frame().image().get(), &play_->current_frame().rect(), &rect);
29 29
     }
30 30
 
... ...
@@ -1,20 +1,20 @@
1 1
 #pragma once
2 2
 
3
-#include "game.h"
4
-#include "nanim.h"
5
-#include "assets.h"
3
+#include "scenimp/game.h"
4
+#include "scenimp/nanim.h"
5
+#include "scenimp/assets.h"
6 6
 
7 7
 namespace superpaflaballe {
8 8
 
9 9
     class intro {
10 10
     public:
11
-        intro(game& g);
11
+        intro(scenimp::game& g);
12 12
         ~intro();
13 13
         void tick();
14 14
         bool is_finished();
15 15
     private:
16
-        game& game_;
17
-        std::shared_ptr<superpaflaballe::nanim::play> play_;
16
+        scenimp::game& game_;
17
+        std::shared_ptr<scenimp::nanim::play> play_;
18 18
         std::shared_ptr<Mix_Music> music_;
19 19
     };
20 20
 
... ...
@@ -1,5 +1,5 @@
1
-#include "assets.h"
2
-#include "game.h"
1
+#include "scenimp/assets.h"
2
+#include "scenimp/game.h"
3 3
 #include "framerate.h"
4 4
 #include "intro.h"
5 5
 #include "bourrines_benchmark.h"
... ...
@@ -24,7 +24,7 @@ namespace superpaflaballe {
24 24
         struct state_outro;
25 25
 
26 26
         struct machine : boost::statechart::state_machine< machine, state_running > {
27
-            game game_;
27
+            scenimp::game game_;
28 28
             framerate framerate_;
29 29
         };
30 30
 
31 31
deleted file mode 100644
... ...
@@ -1,86 +0,0 @@
1
-#include "nanim.h"
2
-
3
-namespace superpaflaballe {
4
-    namespace nanim {
5
-
6
-        long frame::duration() const {
7
-            return duration_;
8
-        }
9
-
10
-        std::shared_ptr<SDL_Texture> frame::image() const {
11
-            return image_;
12
-        }
13
-
14
-        const SDL_Rect& frame::rect() const {
15
-            return rect_;
16
-        }
17
-
18
-        play::play(std::shared_ptr<animation> a, play_mode m)
19
-        : animation_(a) {
20
-            start(m);
21
-        }
22
-
23
-        void play::start(play_mode m) {
24
-            state_ = started;
25
-            current_time = 0;
26
-            current_frame_index_ = 0;
27
-            mode_ = m;
28
-        }
29
-
30
-        void play::stop() {
31
-            state_ = stopped;
32
-            current_time = 0;
33
-            current_frame_index_ = 0;
34
-        }
35
-
36
-        bool play::is_stopped() const {
37
-            return state_ == stopped;
38
-        }
39
-
40
-        play_mode play::mode() const {
41
-            return mode_;
42
-        }
43
-
44
-        void play::update(long elapsed_time) {
45
-            if (state_ == stopped) {
46
-                return;
47
-            }
48
-            current_time += elapsed_time;
49
-            if (current_time >= animation_->total_duration_) {
50
-                switch (mode_) {
51
-                    case once:
52
-                        current_frame_index_ = animation_->frames_.size() - 1;
53
-                        state_ = stopped;
54
-                        return;
55
-                    case loop:
56
-                        current_time %= animation_->total_duration_;
57
-                        current_frame_index_ = 0;
58
-                        break;
59
-                }
60
-            }
61
-            while (current_time > animation_->frames_[current_frame_index_].end_time_) {
62
-                ++current_frame_index_;
63
-            }
64
-        }
65
-
66
-        const frame& play::current_frame() const {
67
-            return animation_->frames_[current_frame_index_];
68
-        }
69
-
70
-        std::shared_ptr<::superpaflaballe::nanim::play> animation::play(play_mode m) {
71
-            return std::make_shared<::superpaflaballe::nanim::play>(shared_from_this(), m);
72
-        }
73
-
74
-        std::shared_ptr<animation> collection::get(const std::string& name) {
75
-            return animations_[name];
76
-        }
77
-
78
-        std::shared_ptr<animation> collection::first() {
79
-            return animations_.begin()->second;
80
-        }
81
-        
82
-        std::shared_ptr<::superpaflaballe::nanim::play> collection::play(play_mode m) {
83
-            return first()->play(m);
84
-        }
85
-    }
86
-}
87 0
deleted file mode 100644
... ...
@@ -1,86 +0,0 @@
1
-#pragma once
2
-
3
-#include <SDL.h>
4
-#include <memory>
5
-#include <map>
6
-#include <vector>
7
-
8
-namespace superpaflaballe {
9
-    class assets;
10
-
11
-    namespace nanim {
12
-
13
-        class collection;
14
-        class animation;
15
-        class play;
16
-
17
-        class frame {
18
-        public:
19
-            long duration() const;
20
-            std::shared_ptr<SDL_Texture> image() const;
21
-            const SDL_Rect& rect() const;
22
-        private:
23
-            long duration_;
24
-            std::shared_ptr<SDL_Texture> image_;
25
-            SDL_Rect rect_;
26
-            long end_time_;
27
-
28
-            friend class ::superpaflaballe::assets;
29
-            friend class play;
30
-        };
31
-
32
-        enum play_mode {
33
-            once,
34
-            loop
35
-        };
36
-
37
-        class play {
38
-        public:
39
-            play(std::shared_ptr<animation> a, play_mode m);
40
-            void start(play_mode m);
41
-            void stop();
42
-            bool is_stopped() const;
43
-            play_mode mode() const;
44
-            void update(long elapsed_time);
45
-            const frame& current_frame() const;
46
-        private:
47
-
48
-            enum state {
49
-                started,
50
-                stopped
51
-            };
52
-            std::shared_ptr<animation> animation_;
53
-            int current_frame_index_;
54
-            long current_time;
55
-            play_mode mode_;
56
-            state state_;
57
-        };
58
-
59
-        class animation : public std::enable_shared_from_this<animation> {
60
-        public:
61
-
62
-            std::shared_ptr<::superpaflaballe::nanim::play> play(play_mode m);
63
-
64
-        private:
65
-            std::vector<frame> frames_;
66
-            long total_duration_;
67
-
68
-            friend class ::superpaflaballe::assets;
69
-            friend class ::superpaflaballe::nanim::play;
70
-        };
71
-
72
-        class collection {
73
-        public:
74
-            std::shared_ptr<animation> get(const std::string& name);
75
-            std::shared_ptr<animation> first();            
76
-            std::shared_ptr<::superpaflaballe::nanim::play> play(play_mode m);
77
-
78
-        private:
79
-            std::map< std::string, std::shared_ptr<animation> > animations_;
80
-
81
-            friend class ::superpaflaballe::assets;
82
-        };
83
-    }
84
-
85
-}
86
-
87 0
new file mode 100644
... ...
@@ -0,0 +1,160 @@
1
+#include "assets.h"
2
+#include "game.h"
3
+#include "sdl_exception.h"
4
+#include <SDL_image.h>
5
+#include <boost/property_tree/ptree.hpp>
6
+#include <boost/property_tree/json_parser.hpp>
7
+#include <boost/filesystem/path.hpp>
8
+#include <boost/filesystem/operations.hpp>
9
+
10
+namespace scenimp {
11
+
12
+    assets::assets(game& game)
13
+    : game_(game) {
14
+        pathPrefixes_.push_back("../assets/");
15
+        pathPrefixes_.push_back(PREFIX "/games/superpaflaballe/");
16
+        if (TTF_Init() != 0) {
17
+            throw sdl_exception();
18
+        }
19
+        const int img_flags = IMG_INIT_PNG;
20
+        int img_initted = IMG_Init(img_flags);
21
+        if ((img_initted & img_flags) != img_flags) {
22
+            throw sdl_exception();
23
+        }
24
+        int mix_flags = MIX_INIT_OGG;
25
+        int mix_initted = Mix_Init(mix_flags);
26
+        if ((mix_initted & mix_flags) != mix_flags) {
27
+            throw sdl_exception();
28
+        }
29
+       if( Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT , 2, 1024) != 0 ) {
30
+            throw sdl_exception();
31
+        }
32
+    }
33
+
34
+    assets::~assets() {
35
+        Mix_CloseAudio();
36
+        Mix_Quit();
37
+        IMG_Quit();
38
+        TTF_Quit();
39
+    }
40
+
41
+    std::shared_ptr< TTF_Font > assets::font(const std::string& path, int size) {
42
+        auto key = std::make_pair(path, size);
43
+        auto font = fonts_[key].lock();
44
+        if (font) {
45
+            return font;
46
+        }
47
+        boost::filesystem::path fspath(path);
48
+        for (auto& prefix : pathPrefixes_) {
49
+            boost::filesystem::path fsprefix(prefix);
50
+            font = load_font((fsprefix / fspath).string(), size);
51
+            if (font) {
52
+                fonts_[key] = font;
53
+                return font;
54
+            }
55
+        }
56
+        throw std::runtime_error("Cannot load font " + path);
57
+    }
58
+
59
+    std::shared_ptr< TTF_Font > assets::load_font(const std::string path, int size) {
60
+        return std::shared_ptr< TTF_Font >(TTF_OpenFont(path.c_str(), size), TTF_CloseFont);
61
+    }
62
+
63
+    std::shared_ptr< Mix_Music > assets::music(const std::string& path) {
64
+        auto music = musics_[path].lock();
65
+        if (music) {
66
+            return music;
67
+        }
68
+        boost::filesystem::path fspath(path);
69
+        for (auto& prefix : pathPrefixes_) {
70
+            boost::filesystem::path fsprefix(prefix);
71
+            music = load_music((fsprefix / fspath).string());
72
+            if (music) {
73
+                musics_[path] = music;
74
+                return music;
75
+            }
76
+        }
77
+        throw std::runtime_error("Cannot load music " + path);
78
+    }
79
+
80
+     std::shared_ptr< Mix_Music > assets::load_music(const std::string& path) {
81
+        return std::shared_ptr< Mix_Music >(Mix_LoadMUS(path.c_str()), Mix_FreeMusic);
82
+    }
83
+
84
+    std::shared_ptr< SDL_Texture > assets::texture(const std::string& path) {
85
+        auto texture = textures_[path].lock();
86
+        if (texture) {
87
+            return texture;
88
+        }
89
+        boost::filesystem::path fspath(path);
90
+        for (auto& prefix : pathPrefixes_) {
91
+            boost::filesystem::path fsprefix(prefix);
92
+            texture = load_texture((fsprefix / fspath).string());
93
+            if (texture) {
94
+                textures_[path] = texture;
95
+                return texture;
96
+            }
97
+        }
98
+        throw std::runtime_error("Cannot load texture " + path);
99
+    }
100
+
101
+    std::shared_ptr< SDL_Texture > assets::load_texture(const std::string path) {
102
+        return std::shared_ptr< SDL_Texture >(IMG_LoadTexture(game_.renderer(), path.c_str()), SDL_DestroyTexture);
103
+    }
104
+
105
+    std::shared_ptr< nanim::collection > assets::animations(const std::string& path) {
106
+        auto animations = animations_[path].lock();
107
+        if (animations) {
108
+            return animations;
109
+        }
110
+        for (auto& prefix : pathPrefixes_) {
111
+            try {
112
+                animations = load_json_nanim(prefix + path);
113
+                if (animations) {
114
+                    animations_[path] = animations;
115
+                    return animations;
116
+                }
117
+            } catch (...) {
118
+            }
119
+        }
120
+        throw std::runtime_error("Cannot load animations " + path);
121
+    }
122
+
123
+    std::shared_ptr<nanim::collection> assets::load_json_nanim(const std::string& path) {
124
+        using boost::property_tree::ptree;
125
+        if (!boost::filesystem::exists(path)) {
126
+            return nullptr;
127
+        }
128
+        ptree pt_nanim;
129
+        boost::property_tree::read_json(path, pt_nanim);
130
+        boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path();
131
+        auto collec = std::make_shared<nanim::collection>();
132
+
133
+        for (auto& pt_animation : pt_nanim.get_child("animations")) {
134
+            auto anim = std::make_shared<nanim::animation>();
135
+            for (auto& pt_frame_child : pt_animation.second.get_child("frames")) {
136
+                auto pt_frame = pt_frame_child.second;
137
+                nanim::frame fram;
138
+                fram.duration_ = pt_frame.get<long>("duration");
139
+                anim->total_duration_ += fram.duration_;
140
+                fram.end_time_ = anim->total_duration_;
141
+                float u1 = pt_frame.get<float>("u1");
142
+                float v1 = pt_frame.get<float>("v1");
143
+                float u2 = pt_frame.get<float>("u2");
144
+                float v2 = pt_frame.get<float>("v2");
145
+                fram.image_ = load_texture((parent_path / pt_frame.get<std::string>("image")).string());
146
+                int w, h;
147
+                SDL_QueryTexture(fram.image_.get(), NULL, NULL, &w, &h);
148
+                fram.rect_.x = u1 * w;
149
+                fram.rect_.y = v1 * w;
150
+                fram.rect_.w = (u2 - u1) * w;
151
+                fram.rect_.h = (v2 - v1) * h;
152
+                anim->frames_.push_back(fram);
153
+            }
154
+            std::string name = pt_animation.second.get<std::string>("name");
155
+            collec->animations_[name] = anim;
156
+        }
157
+        return collec;
158
+    }
159
+
160
+}
0 161
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+#pragma once
2
+
3
+#include "nanim.h"
4
+#include <SDL_mixer.h>
5
+#include <SDL_ttf.h>
6
+
7
+namespace scenimp {
8
+
9
+    class game;
10
+
11
+    class assets {
12
+    public:
13
+        assets(game& game);
14
+        ~assets();
15
+
16
+        std::shared_ptr< nanim::collection > animations(const std::string& path);
17
+        std::shared_ptr< TTF_Font > font(const std::string& path, int size);
18
+        std::shared_ptr< Mix_Music > music(const std::string& path);
19
+        std::shared_ptr< SDL_Texture > texture(const std::string& path);
20
+
21
+
22
+    private:
23
+        std::shared_ptr< TTF_Font > load_font(const std::string path, int size);
24
+        std::shared_ptr<nanim::collection> load_json_nanim(const std::string& path);
25
+        std::shared_ptr< Mix_Music > load_music(const std::string& path);
26
+        std::shared_ptr< SDL_Texture > load_texture(const std::string path);
27
+
28
+        game& game_;
29
+        std::vector<std::string> pathPrefixes_;
30
+        std::map<std::string, std::weak_ptr< nanim::collection > > animations_;
31
+        std::map<std::pair<std::string, int/*font size*/>, std::weak_ptr< TTF_Font > > fonts_;
32
+        std::map<std::string, std::weak_ptr< SDL_Texture > > textures_;
33
+        std::map<std::string, std::weak_ptr< Mix_Music > > musics_;
34
+    };
35
+
36
+}
0 37
new file mode 100644
... ...
@@ -0,0 +1,51 @@
1
+#include "game.h"
2
+#include "sdl_exception.h"
3
+
4
+#include <SDL.h>
5
+
6
+namespace scenimp {
7
+
8
+    game::game() {
9
+        if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
10
+            throw sdl_exception();
11
+        }
12
+        window_ = SDL_CreateWindow("superpaflaballe", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 360, SDL_WINDOW_RESIZABLE);
13
+        if (!window_) {
14
+            SDL_Quit();
15
+            throw sdl_exception();
16
+        }
17
+        renderer_ = SDL_CreateRenderer(window_, -1, 0);
18
+        if (!renderer_) {
19
+            SDL_DestroyWindow(window_);
20
+            SDL_Quit();
21
+            throw sdl_exception();
22
+        }
23
+        SDL_RenderSetLogicalSize(renderer_, logical_screen_width, logical_screen_height);
24
+        assets_ = new scenimp::assets(*this);
25
+    }
26
+
27
+    game::~game() {
28
+        delete assets_;
29
+        SDL_DestroyRenderer(renderer_);
30
+        SDL_DestroyWindow(window_);
31
+        SDL_Quit();
32
+    }
33
+
34
+    SDL_Window* game::window() {
35
+        return window_;
36
+    }
37
+
38
+    SDL_Renderer* game::renderer() {
39
+        return renderer_;
40
+    }
41
+
42
+    assets& game::assets() {
43
+        return *assets_;
44
+    }
45
+
46
+    std::shared_ptr< SDL_Texture > game::create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color) {
47
+        std::unique_ptr<SDL_Surface, void (*)(SDL_Surface *) > text_surface(TTF_RenderText_Blended(font.get(), str.c_str(), color), SDL_FreeSurface);
48
+        return std::shared_ptr< SDL_Texture >(SDL_CreateTextureFromSurface(renderer(), text_surface.get()), SDL_DestroyTexture);
49
+    }
50
+
51
+}
0 52
new file mode 100644
... ...
@@ -0,0 +1,28 @@
1
+#pragma once
2
+
3
+#include "assets.h"
4
+
5
+namespace scenimp {
6
+
7
+    const int logical_screen_width = 1920;
8
+    const int logical_screen_height = 1080;
9
+
10
+    class game {
11
+    public:
12
+        game();
13
+        ~game();
14
+
15
+        SDL_Window* window();
16
+        SDL_Renderer* renderer();
17
+        scenimp::assets& assets();
18
+
19
+        std::shared_ptr< SDL_Texture > create_text_texture(std::shared_ptr< TTF_Font > font, const std::string& str, const SDL_Color& color = {255, 255, 255, 0});
20
+
21
+    private:
22
+        scenimp::assets* assets_;
23
+        SDL_Window* window_;
24
+        SDL_Renderer* renderer_;
25
+    };
26
+
27
+}
28
+
0 29
new file mode 100644
... ...
@@ -0,0 +1,25 @@
1
+#include "group.h"
2
+
3
+namespace scenimp {
4
+
5
+    group::group() {
6
+    }
7
+
8
+    group::~group() {
9
+    }
10
+
11
+    void group::attach(std::shared_ptr<node> node) {
12
+        node->parent_ = std::static_pointer_cast<group>(shared_from_this());
13
+        children_.insert(node);
14
+    }
15
+
16
+    void group::detach(std::shared_ptr<node> node) {
17
+        node->parent_.reset();
18
+        children_.erase(node);
19
+    }
20
+
21
+    const node_list& group::children() const {
22
+        return children_;
23
+    }
24
+
25
+}
0 26
new file mode 100644
... ...
@@ -0,0 +1,24 @@
1
+#pragma once
2
+
3
+#include "node.h"
4
+
5
+namespace scenimp {
6
+
7
+    class group : public node {
8
+    public:
9
+        group();
10
+        group(const group& orig) = delete;
11
+        virtual ~group();
12
+
13
+        void attach(std::shared_ptr< node > node);
14
+        void detach(std::shared_ptr< node > node);
15
+
16
+        const node_list& children() const;
17
+
18
+    private:
19
+        node_list children_;
20
+    };
21
+
22
+}
23
+
24
+
0 25
new file mode 100644
... ...
@@ -0,0 +1,86 @@
1
+#include "nanim.h"
2
+
3
+namespace scenimp {
4
+    namespace nanim {
5
+
6
+        long frame::duration() const {
7
+            return duration_;
8
+        }
9
+
10
+        std::shared_ptr<SDL_Texture> frame::image() const {
11
+            return image_;
12
+        }
13
+
14
+        const SDL_Rect& frame::rect() const {
15
+            return rect_;
16
+        }
17
+
18
+        play::play(std::shared_ptr<animation> a, play_mode m)
19
+        : animation_(a) {
20
+            start(m);
21
+        }
22
+
23
+        void play::start(play_mode m) {
24
+            state_ = started;
25
+            current_time = 0;
26
+            current_frame_index_ = 0;
27
+            mode_ = m;
28
+        }
29
+
30
+        void play::stop() {
31
+            state_ = stopped;
32
+            current_time = 0;
33
+            current_frame_index_ = 0;
34
+        }
35
+
36
+        bool play::is_stopped() const {
37
+            return state_ == stopped;
38
+        }
39
+
40
+        play_mode play::mode() const {
41
+            return mode_;
42
+        }
43
+
44
+        void play::update(long elapsed_time) {
45
+            if (state_ == stopped) {
46
+                return;
47
+            }
48
+            current_time += elapsed_time;
49
+            if (current_time >= animation_->total_duration_) {
50
+                switch (mode_) {
51
+                    case once:
52
+                        current_frame_index_ = animation_->frames_.size() - 1;
53
+                        state_ = stopped;
54
+                        return;
55
+                    case loop:
56
+                        current_time %= animation_->total_duration_;
57
+                        current_frame_index_ = 0;
58
+                        break;
59
+                }
60
+            }
61
+            while (current_time > animation_->frames_[current_frame_index_].end_time_) {
62
+                ++current_frame_index_;
63
+            }
64
+        }
65
+
66
+        const frame& play::current_frame() const {
67
+            return animation_->frames_[current_frame_index_];
68
+        }
69
+
70
+        std::shared_ptr<::scenimp::nanim::play> animation::play(play_mode m) {
71
+            return std::make_shared<::scenimp::nanim::play>(shared_from_this(), m);
72
+        }
73
+
74
+        std::shared_ptr<animation> collection::get(const std::string& name) {
75
+            return animations_[name];
76
+        }
77
+
78
+        std::shared_ptr<animation> collection::first() {
79
+            return animations_.begin()->second;
80
+        }
81
+        
82
+        std::shared_ptr<::scenimp::nanim::play> collection::play(play_mode m) {
83
+            return first()->play(m);
84
+        }
85
+    }
86
+}
0 87
new file mode 100644
... ...
@@ -0,0 +1,86 @@
1
+#pragma once
2
+
3
+#include <SDL.h>
4
+#include <memory>
5
+#include <map>
6
+#include <vector>
7
+
8
+namespace scenimp {
9
+    class assets;
10
+
11
+    namespace nanim {
12
+
13
+        class collection;
14
+        class animation;
15
+        class play;
16
+
17
+        class frame {
18
+        public:
19
+            long duration() const;
20
+            std::shared_ptr<SDL_Texture> image() const;
21
+            const SDL_Rect& rect() const;
22
+        private:
23
+            long duration_;
24
+            std::shared_ptr<SDL_Texture> image_;
25
+            SDL_Rect rect_;
26
+            long end_time_;
27
+
28
+            friend class ::scenimp::assets;
29
+            friend class play;
30
+        };
31
+
32
+        enum play_mode {
33
+            once,
34
+            loop
35
+        };
36
+
37
+        class play {
38
+        public:
39
+            play(std::shared_ptr<animation> a, play_mode m);
40
+            void start(play_mode m);
41
+            void stop();
42
+            bool is_stopped() const;
43
+            play_mode mode() const;
44
+            void update(long elapsed_time);
45
+            const frame& current_frame() const;
46
+        private:
47
+
48
+            enum state {
49
+                started,
50
+                stopped
51
+            };
52
+            std::shared_ptr<animation> animation_;
53
+            int current_frame_index_;
54
+            long current_time;
55
+            play_mode mode_;
56
+            state state_;
57
+        };
58
+
59
+        class animation : public std::enable_shared_from_this<animation> {
60
+        public:
61
+
62
+            std::shared_ptr<::scenimp::nanim::play> play(play_mode m);
63
+
64
+        private:
65
+            std::vector<frame> frames_;
66
+            long total_duration_;
67
+
68
+            friend class ::scenimp::assets;
69
+            friend class ::scenimp::nanim::play;
70
+        };
71
+
72
+        class collection {
73
+        public:
74
+            std::shared_ptr<animation> get(const std::string& name);
75
+            std::shared_ptr<animation> first();            
76
+            std::shared_ptr<::scenimp::nanim::play> play(play_mode m);
77
+
78
+        private:
79
+            std::map< std::string, std::shared_ptr<animation> > animations_;
80
+
81
+            friend class ::scenimp::assets;
82
+        };
83
+    }
84
+
85
+}
86
+
0 87
new file mode 100644
... ...
@@ -0,0 +1,18 @@
1
+#include "node.h"
2
+#include "group.h"
3
+
4
+namespace scenimp {
5
+
6
+    node::node() {
7
+    }
8
+
9
+    node::~node() {
10
+    }
11
+
12
+    void node::detach() {
13
+        if (auto lockedParent = parent_.lock()) {
14
+            lockedParent->detach(shared_from_this());
15
+        }
16
+    }
17
+
18
+}
0 19
new file mode 100644
... ...
@@ -0,0 +1,28 @@
1
+#pragma once
2
+
3
+#include <memory>
4
+#include <boost/container/flat_set.hpp>
5
+
6
+namespace scenimp {
7
+    
8
+    class group;
9
+
10
+    class node: public std::enable_shared_from_this<node> {
11
+    public:
12
+        node();
13
+        node(const node& orig) = delete;
14
+        virtual ~node();
15
+        
16
+        void detach();
17
+
18
+    private:
19
+        std::weak_ptr<group> parent_;
20
+        
21
+        friend class group;
22
+    };
23
+
24
+    typedef boost::container::flat_set< std::shared_ptr<node> > node_list;
25
+
26
+}
27
+
28
+
0 29
new file mode 100644
... ...
@@ -0,0 +1,10 @@
1
+#include "sdl_exception.h"
2
+
3
+namespace scenimp {
4
+
5
+sdl_exception::sdl_exception()
6
+    : runtime_error(SDL_GetError())
7
+{
8
+}
9
+
10
+}
0 11
new file mode 100644
... ...
@@ -0,0 +1,14 @@
1
+#pragma once
2
+
3
+#include <SDL.h>
4
+#include <stdexcept>
5
+
6
+namespace scenimp {
7
+
8
+class sdl_exception : public std::runtime_error
9
+{
10
+public:
11
+    sdl_exception();
12
+};
13
+
14
+}
0 15
new file mode 100644
... ...
@@ -0,0 +1,11 @@
1
+#include "sprite.h"
2
+
3
+namespace scenimp {
4
+
5
+    sprite::sprite() {
6
+    }
7
+
8
+    sprite::~sprite() {
9
+    }
10
+
11
+}
0 12
new file mode 100644
... ...
@@ -0,0 +1,19 @@
1
+#pragma once
2
+
3
+#include "node.h"
4
+#include "nanim.h"
5
+
6
+namespace scenimp {
7
+
8
+    class sprite : public node {
9
+    public:
10
+        sprite();
11
+        sprite(const sprite& orig) = delete;
12
+        virtual ~sprite();
13
+    private:
14
+        std::shared_ptr< nanim::play > play_;
15
+    };
16
+
17
+}
18
+
19
+
0 20
deleted file mode 100644
... ...
@@ -1,10 +0,0 @@
1
-#include "sdl_exception.h"
2
-
3
-namespace superpaflaballe {
4
-
5
-sdl_exception::sdl_exception()
6
-    : runtime_error(SDL_GetError())
7
-{
8
-}
9
-
10
-}
11 0
deleted file mode 100644
... ...
@@ -1,14 +0,0 @@
1
-#pragma once
2
-
3
-#include <SDL.h>
4
-#include <stdexcept>
5
-
6
-namespace superpaflaballe {
7
-
8
-class sdl_exception : public std::runtime_error
9
-{
10
-public:
11
-    sdl_exception();
12
-};
13
-
14
-}