]> git.localhorst.tv Git - blobs.git/blob - src/app/app.cpp
simple planet render
[blobs.git] / src / app / app.cpp
1 #include "Application.hpp"
2 #include "Assets.hpp"
3 #include "State.hpp"
4
5 #include "init.hpp"
6 #include "../graphics/Viewport.hpp"
7
8 #include <SDL.h>
9
10
11 namespace blobs {
12 namespace app {
13
14 Application::Application(Window &win, graphics::Viewport &vp)
15 : window(win)
16 , viewport(vp)
17 , states() {
18 }
19
20 Application::~Application() {
21 }
22
23
24 void Application::PushState(State *s) {
25         s->app = this;
26         if (!states.empty()) {
27                 states.top()->OnPause();
28         }
29         states.emplace(s);
30         ++s->ref_count;
31         if (s->ref_count == 1) {
32                 s->OnEnter();
33         }
34         s->OnResume();
35 }
36
37 State *Application::PopState() {
38         State *s = states.top();
39         states.pop();
40         s->OnPause();
41         s->OnExit();
42         if (!states.empty()) {
43                 states.top()->OnResume();
44         }
45         return s;
46 }
47
48 State *Application::SwitchState(State *s_new) {
49         s_new->app = this;
50         State *s_old = states.top();
51         states.top() = s_new;
52         --s_old->ref_count;
53         ++s_new->ref_count;
54         s_old->OnPause();
55         if (s_old->ref_count == 0) {
56                 s_old->OnExit();
57         }
58         if (s_new->ref_count == 1) {
59                 s_new->OnEnter();
60         }
61         s_new->OnResume();
62         return s_old;
63 }
64
65 State &Application::GetState() {
66         return *states.top();
67 }
68
69 bool Application::HasState() const noexcept {
70         return !states.empty();
71 }
72
73
74 void Application::Run() {
75         Uint32 last = SDL_GetTicks();
76         while (HasState()) {
77                 Uint32 now = SDL_GetTicks();
78                 int delta = now - last;
79                 Loop(delta);
80                 last = now;
81         }
82 }
83
84 void Application::Loop(int dt) {
85         HandleEvents();
86         if (!HasState()) return;
87         GetState().Update(dt);
88         if (!HasState()) return;
89         viewport.Clear();
90         GetState().Render(viewport);
91         window.Flip();
92 }
93
94 void Application::HandleEvents() {
95         SDL_Event event;
96         while (HasState() && SDL_PollEvent(&event)) {
97                 if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED) {
98                         viewport.Resize(event.window.data1, event.window.data2);
99                 }
100                 GetState().Handle(event);
101         }
102 }
103
104 void State::Handle(const SDL_Event &event) {
105         switch (event.type) {
106                 case SDL_KEYDOWN:
107                         OnKeyDown(event.key);
108                         break;
109                 case SDL_KEYUP:
110                         OnKeyUp(event.key);
111                         break;
112                 case SDL_MOUSEBUTTONDOWN:
113                         OnMouseDown(event.button);
114                         break;
115                 case SDL_MOUSEBUTTONUP:
116                         OnMouseUp(event.button);
117                         break;
118                 case SDL_MOUSEMOTION:
119                         OnMouseMotion(event.motion);
120                         break;
121                 case SDL_MOUSEWHEEL:
122                         OnMouseWheel(event.wheel);
123                         break;
124                 case SDL_QUIT:
125                         OnQuit();
126                         break;
127                 case SDL_WINDOWEVENT:
128                         Handle(event.window);
129                         break;
130                 default:
131                         // ignore
132                         break;
133         }
134 }
135
136 void State::Handle(const SDL_WindowEvent &event) {
137         switch (event.event) {
138                 case SDL_WINDOWEVENT_FOCUS_GAINED:
139                         OnFocus();
140                         break;
141                 case SDL_WINDOWEVENT_FOCUS_LOST:
142                         OnBlur();
143                         break;
144                 case SDL_WINDOWEVENT_RESIZED:
145                         OnResize(event.data1, event.data2);
146                         break;
147                 default:
148                         break;
149         }
150 }
151
152 void State::Update(int dt) {
153         OnUpdate(dt);
154 }
155
156 void State::Render(graphics::Viewport &viewport) {
157         OnRender(viewport);
158 }
159
160 void State::OnQuit() {
161         while (App().HasState()) {
162                 App().PopState();
163         }
164 }
165
166
167 Assets::Assets() {
168         graphics::Format format;
169         textures.tiles.Bind();
170         textures.tiles.Reserve(1, 1, 3, format);
171         std::uint8_t texdata[] = {
172                 0xFF, 0x00, 0x00, 0xFF,
173                 0x00, 0xFF, 0x00, 0xFF,
174                 0x00, 0x00, 0xFF, 0xFF,
175         };
176         textures.tiles.Data(0, format, texdata);
177         textures.tiles.Data(1, format, texdata + 4);
178         textures.tiles.Data(2, format, texdata + 8);
179 }
180
181 Assets::~Assets() {
182 }
183
184 }
185 }