1 #include "Application.hpp"
3 #include "FrameCounter.hpp"
6 #include "../audio/Sound.hpp"
7 #include "../graphics/Font.hpp"
8 #include "../world/BlockType.hpp"
9 #include "../world/Entity.hpp"
19 string get_asset_path() {
20 char *base = SDL_GetBasePath();
31 Application::Application(Window &win, const Config &config)
34 , assets(get_asset_path())
38 , interface(config.interface, assets, audio, counter, world)
41 viewport.VSync(config.vsync);
44 Application::~Application() {
49 void Application::RunN(size_t n) {
50 Uint32 last = SDL_GetTicks();
51 for (size_t i = 0; i < n; ++i) {
52 Uint32 now = SDL_GetTicks();
53 int delta = now - last;
59 void Application::RunT(size_t t) {
60 Uint32 last = SDL_GetTicks();
61 Uint32 finish = last + t;
62 while (last < finish) {
63 Uint32 now = SDL_GetTicks();
64 int delta = now - last;
70 void Application::RunS(size_t n, size_t t) {
71 for (size_t i = 0; i < n; ++i) {
77 void Application::Run() {
79 Uint32 last = SDL_GetTicks();
82 Uint32 now = SDL_GetTicks();
83 int delta = now - last;
89 void Application::Loop(int dt) {
98 void Application::HandleEvents() {
99 counter.EnterHandle();
101 while (SDL_PollEvent(&event)) {
102 switch (event.type) {
104 interface.HandlePress(event.key);
107 interface.HandleRelease(event.key);
109 case SDL_MOUSEBUTTONDOWN:
110 interface.HandlePress(event.button);
112 case SDL_MOUSEBUTTONUP:
113 interface.HandleRelease(event.button);
115 case SDL_MOUSEMOTION:
116 interface.Handle(event.motion);
119 interface.Handle(event.wheel);
124 case SDL_WINDOWEVENT:
125 Handle(event.window);
131 counter.ExitHandle();
134 void Application::Handle(const SDL_WindowEvent &event) {
135 switch (event.event) {
136 case SDL_WINDOWEVENT_FOCUS_GAINED:
139 case SDL_WINDOWEVENT_FOCUS_LOST:
140 window.ReleaseMouse();
142 case SDL_WINDOWEVENT_RESIZED:
143 viewport.Resize(event.data1, event.data2);
150 void Application::Update(int dt) {
151 counter.EnterUpdate();
152 interface.Update(dt);
156 glm::mat4 trans = world.Player().Transform(Chunk::Pos(0, 0, 0));
157 glm::vec3 dir(trans * glm::vec4(0.0f, 0.0f, -1.0f, 0.0f));
158 glm::vec3 up(trans * glm::vec4(0.0f, 1.0f, 0.0f, 0.0f));
159 audio.Position(world.Player().Position());
160 audio.Velocity(world.Player().Velocity());
161 audio.Orientation(dir, up);
163 counter.ExitUpdate();
166 void Application::Render() {
167 // gl implementation may (and will probably) delay vsync blocking until
168 // the first write after flipping, which is this clear call
170 counter.EnterRender();
172 world.Render(viewport);
173 interface.Render(viewport);
175 counter.ExitRender();
180 Assets::Assets(const string &base)
181 : fonts(base + "fonts/")
182 , sounds(base + "sounds/") {
186 Font Assets::LoadFont(const string &name, int size) const {
187 string full = fonts + name + ".ttf";
188 return Font(full.c_str(), size);
191 Sound Assets::LoadSound(const string &name) const {
192 string full = sounds + name + ".wav";
193 return Sound(full.c_str());
197 void FrameCounter::EnterFrame() noexcept {
198 last_enter = SDL_GetTicks();
199 last_tick = last_enter;
202 void FrameCounter::EnterHandle() noexcept {
206 void FrameCounter::ExitHandle() noexcept {
207 current.handle = Tick();
210 void FrameCounter::EnterUpdate() noexcept {
214 void FrameCounter::ExitUpdate() noexcept {
215 current.update = Tick();
218 void FrameCounter::EnterRender() noexcept {
222 void FrameCounter::ExitRender() noexcept {
223 current.render = Tick();
226 void FrameCounter::ExitFrame() noexcept {
227 Uint32 now = SDL_GetTicks();
228 current.total = now - last_enter;
229 current.running = current.handle + current.update + current.render;
230 current.waiting = current.total - current.running;
234 if (cur_frame >= NUM_FRAMES) {
243 int FrameCounter::Tick() noexcept {
244 Uint32 now = SDL_GetTicks();
245 int delta = now - last_tick;
250 void FrameCounter::Accumulate() noexcept {
251 sum.handle += current.handle;
252 sum.update += current.update;
253 sum.render += current.render;
254 sum.running += current.running;
255 sum.waiting += current.waiting;
256 sum.total += current.total;
258 max.handle = std::max(current.handle, max.handle);
259 max.update = std::max(current.update, max.update);
260 max.render = std::max(current.render, max.render);
261 max.running = std::max(current.running, max.running);
262 max.waiting = std::max(current.waiting, max.waiting);
263 max.total = std::max(current.total, max.total);
265 current = Frame<int>();
268 void FrameCounter::Push() noexcept {
270 avg.handle = sum.handle * factor;
271 avg.update = sum.update * factor;
272 avg.render = sum.render * factor;
273 avg.running = sum.running * factor;
274 avg.waiting = sum.waiting * factor;
275 avg.total = sum.total * factor;