1 #include "Application.hpp"
3 #include "FrameCounter.hpp"
5 #include "../graphics/Font.hpp"
6 #include "../world/BlockType.hpp"
7 #include "../world/Entity.hpp"
17 string get_asset_path() {
18 char *base = SDL_GetBasePath();
29 Application::Application(const Config &config)
30 : init(config.doublebuf, config.multisampling)
32 , assets(get_asset_path())
35 , interface(config.interface, assets, counter, world)
36 , test_controller(MakeTestEntity(world))
38 viewport.VSync(config.vsync);
41 Entity &Application::MakeTestEntity(World &world) {
42 Entity &e = world.AddEntity();
44 e.Position({ 0.0f, 0.0f, 0.0f });
45 e.Bounds({ { -0.5f, -0.5f, -0.5f }, { 0.5f, 0.5f, 0.5f } });
46 e.WorldCollidable(true);
47 e.SetShape(world.BlockTypes()[1].shape, { 1.0f, 1.0f, 0.0f });
48 e.AngularVelocity(glm::quat(glm::vec3{ 0.00001f, 0.000006f, 0.000013f }));
53 void Application::RunN(size_t n) {
54 Uint32 last = SDL_GetTicks();
55 for (size_t i = 0; i < n; ++i) {
56 Uint32 now = SDL_GetTicks();
57 int delta = now - last;
63 void Application::RunT(size_t t) {
64 Uint32 last = SDL_GetTicks();
65 Uint32 finish = last + t;
66 while (last < finish) {
67 Uint32 now = SDL_GetTicks();
68 int delta = now - last;
74 void Application::RunS(size_t n, size_t t) {
75 for (size_t i = 0; i < n; ++i) {
81 void Application::Run() {
83 Uint32 last = SDL_GetTicks();
84 init.window.GrabMouse();
86 Uint32 now = SDL_GetTicks();
87 int delta = now - last;
93 void Application::Loop(int dt) {
102 void Application::HandleEvents() {
103 counter.EnterHandle();
105 while (SDL_PollEvent(&event)) {
106 switch (event.type) {
108 interface.HandlePress(event.key);
111 interface.HandleRelease(event.key);
113 case SDL_MOUSEBUTTONDOWN:
114 interface.HandlePress(event.button);
116 case SDL_MOUSEBUTTONUP:
117 interface.HandleRelease(event.button);
119 case SDL_MOUSEMOTION:
120 interface.Handle(event.motion);
123 interface.Handle(event.wheel);
128 case SDL_WINDOWEVENT:
129 Handle(event.window);
135 counter.ExitHandle();
138 void Application::Handle(const SDL_WindowEvent &event) {
139 switch (event.event) {
140 case SDL_WINDOWEVENT_FOCUS_GAINED:
141 init.window.GrabMouse();
143 case SDL_WINDOWEVENT_FOCUS_LOST:
144 init.window.ReleaseMouse();
146 case SDL_WINDOWEVENT_RESIZED:
147 viewport.Resize(event.data1, event.data2);
154 void Application::Update(int dt) {
155 counter.EnterUpdate();
156 interface.Update(dt);
157 test_controller.Update(dt);
159 counter.ExitUpdate();
162 void Application::Render() {
163 // gl implementation may (and will probably) delay vsync blocking until
164 // the first write after flipping, which is this clear call
166 counter.EnterRender();
168 world.Render(viewport);
169 interface.Render(viewport);
171 counter.ExitRender();
176 Assets::Assets(const string &base)
177 : fonts(base + "fonts/") {
181 Font Assets::LoadFont(const string &name, int size) const {
182 string full = fonts + name + ".ttf";
183 return Font(full.c_str(), size);
187 void FrameCounter::EnterFrame() noexcept {
188 last_enter = SDL_GetTicks();
189 last_tick = last_enter;
192 void FrameCounter::EnterHandle() noexcept {
196 void FrameCounter::ExitHandle() noexcept {
197 running.handle += Tick();
200 void FrameCounter::EnterUpdate() noexcept {
204 void FrameCounter::ExitUpdate() noexcept {
205 running.update += Tick();
208 void FrameCounter::EnterRender() noexcept {
212 void FrameCounter::ExitRender() noexcept {
213 running.render += Tick();
216 void FrameCounter::ExitFrame() noexcept {
217 Uint32 now = SDL_GetTicks();
218 running.total += now - last_enter;
220 if (cur_frame >= NUM_FRAMES) {
221 avg.handle = running.handle * factor;
222 avg.update = running.update * factor;
223 avg.render = running.render * factor;
224 avg.total = running.total * factor;
225 running = Frame<int>{};
233 int FrameCounter::Tick() noexcept {
234 Uint32 now = SDL_GetTicks();
235 int delta = now - last_tick;
240 void FrameCounter::Print(std::ostream &out) const {
241 out << "frame: " << AvgFrame() << std::endl;
242 out << " handle: " << AvgHandle() << std::endl;
243 out << " update: " << AvgUpdate() << std::endl;
244 out << " render: " << AvgRender() << std::endl;
245 out << " running: " << AvgRunning() << std::endl;
246 out << " waiting: " << AvgWaiting() << std::endl;