+Sound Assets::LoadSound(const string &name) const {
+ string full = sounds + name + ".wav";
+ return Sound(full.c_str());
+}
+
+Texture Assets::LoadTexture(const string &name) const {
+ string full = textures + name + ".png";
+ Texture tex;
+ SDL_Surface *srf = IMG_Load(full.c_str());
+ if (!srf) {
+ throw SDLError("IMG_Load");
+ }
+ tex.Bind();
+ tex.Data(*srf);
+ SDL_FreeSurface(srf);
+ return tex;
+}
+
+void Assets::LoadTexture(const string &name, ArrayTexture &tex, int layer) const {
+ string full = textures + name + ".png";
+ SDL_Surface *srf = IMG_Load(full.c_str());
+ if (!srf) {
+ throw SDLError("IMG_Load");
+ }
+ tex.Bind();
+ try {
+ tex.Data(layer, *srf);
+ } catch (...) {
+ SDL_FreeSurface(srf);
+ throw;
+ }
+ SDL_FreeSurface(srf);
+}
+
+void Assets::LoadTextures(const TextureIndex &index, ArrayTexture &tex) const {
+ // TODO: where the hell should that size come from?
+ tex.Reserve(16, 16, index.Size(), Format());
+ for (const auto &entry : index.Entries()) {
+ LoadTexture(entry.first, tex, entry.second);
+ }
+}
+
+
+TextureIndex::TextureIndex()
+: id_map() {
+
+}
+
+int TextureIndex::GetID(const string &name) {
+ auto entry = id_map.find(name);
+ if (entry == id_map.end()) {
+ auto result = id_map.emplace(name, Size());
+ return result.first->second;
+ } else {
+ return entry->second;
+ }
+}
+
+
+void FrameCounter::EnterFrame() noexcept {
+ last_enter = SDL_GetTicks();
+ last_tick = last_enter;
+}
+
+void FrameCounter::EnterHandle() noexcept {
+ Tick();
+}
+
+void FrameCounter::ExitHandle() noexcept {
+ current.handle = Tick();
+}
+
+void FrameCounter::EnterUpdate() noexcept {
+ Tick();
+}
+
+void FrameCounter::ExitUpdate() noexcept {
+ current.update = Tick();
+}
+
+void FrameCounter::EnterRender() noexcept {
+ Tick();
+}
+
+void FrameCounter::ExitRender() noexcept {
+ current.render = Tick();
+}
+
+void FrameCounter::ExitFrame() noexcept {
+ Uint32 now = SDL_GetTicks();
+ current.total = now - last_enter;
+ current.running = current.handle + current.update + current.render;
+ current.waiting = current.total - current.running;
+ Accumulate();
+
+ ++cur_frame;
+ if (cur_frame >= NUM_FRAMES) {
+ Push();
+ cur_frame = 0;
+ changed = true;
+ } else {
+ changed = false;
+ }
+}
+
+int FrameCounter::Tick() noexcept {
+ Uint32 now = SDL_GetTicks();
+ int delta = now - last_tick;
+ last_tick = now;
+ return delta;
+}
+
+void FrameCounter::Accumulate() noexcept {
+ sum.handle += current.handle;
+ sum.update += current.update;
+ sum.render += current.render;
+ sum.running += current.running;
+ sum.waiting += current.waiting;
+ sum.total += current.total;
+
+ max.handle = std::max(current.handle, max.handle);
+ max.update = std::max(current.update, max.update);
+ max.render = std::max(current.render, max.render);
+ max.running = std::max(current.running, max.running);
+ max.waiting = std::max(current.waiting, max.waiting);
+ max.total = std::max(current.total, max.total);
+
+ current = Frame<int>();
+}
+
+void FrameCounter::Push() noexcept {
+ peak = max;
+ avg.handle = sum.handle * factor;
+ avg.update = sum.update * factor;
+ avg.render = sum.render * factor;
+ avg.running = sum.running * factor;
+ avg.waiting = sum.waiting * factor;
+ avg.total = sum.total * factor;
+
+ sum = Frame<int>();
+ max = Frame<int>();
+}
+