blob: 59b8ed484eb62675407295570d60c0193f34cd06 [file] [log] [blame]
Matt Mowere04eee72016-12-31 00:38:57 -06001/*
2 Copyright 2017 TeamWin
3 This file is part of TWRP/TeamWin Recovery Project.
4
5 TWRP is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 TWRP is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with TWRP. If not, see <http://www.gnu.org/licenses/>.
17*/
18
Dees_Troy51a0e822012-09-05 15:24:24 -040019// resource.cpp - Source to manage GUI resources
20
21#include <stdarg.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040025#include <unistd.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040026
27#include <string>
28#include <sstream>
29#include <iostream>
30#include <iomanip>
Ethan Yonker3fdcda42016-11-30 12:29:37 -060031#include <fcntl.h>
Dees_Troy51a0e822012-09-05 15:24:24 -040032
Ethan Yonker8373cfe2017-09-08 06:50:54 -050033#include "../zipwrap.hpp"
Dees_Troy51a0e822012-09-05 15:24:24 -040034extern "C" {
Dees_Troy2673cec2013-04-02 20:22:16 +000035#include "../twcommon.h"
Ethan Yonker63e414f2015-02-06 15:44:39 -060036#include "gui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040037}
Ethan Yonkerfbb43532015-12-28 21:54:50 +010038#include "../minuitwrp/minui.h"
Dees_Troy51a0e822012-09-05 15:24:24 -040039
40#include "rapidxml.hpp"
41#include "objects.hpp"
42
43#define TMP_RESOURCE_NAME "/tmp/extract.bin"
44
Ethan Yonker8373cfe2017-09-08 06:50:54 -050045Resource::Resource(xml_node<>* node, ZipWrap* pZip __unused)
Dees_Troy51a0e822012-09-05 15:24:24 -040046{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020047 if (node && node->first_attribute("name"))
48 mName = node->first_attribute("name")->value();
Dees_Troy51a0e822012-09-05 15:24:24 -040049}
50
Ethan Yonker8373cfe2017-09-08 06:50:54 -050051int Resource::ExtractResource(ZipWrap* pZip, std::string folderName, std::string fileName, std::string fileExtn, std::string destFile)
Dees_Troy51a0e822012-09-05 15:24:24 -040052{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020053 if (!pZip)
54 return -1;
Dees_Troy51a0e822012-09-05 15:24:24 -040055
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020056 std::string src = folderName + "/" + fileName + fileExtn;
Ethan Yonker8373cfe2017-09-08 06:50:54 -050057 if (!pZip->ExtractEntry(src, destFile, 0666))
Vojtech Bocekfafb0c52013-07-25 22:53:02 +020058 return -1;
Ethan Yonker8373cfe2017-09-08 06:50:54 -050059 return 0;
Dees_Troy51a0e822012-09-05 15:24:24 -040060}
61
Ethan Yonker8373cfe2017-09-08 06:50:54 -050062void Resource::LoadImage(ZipWrap* pZip, std::string file, gr_surface* surface)
Ethan Yonker63e414f2015-02-06 15:44:39 -060063{
thatb240f4a2016-03-14 01:21:38 +010064 int rc = 0;
Ethan Yonker63e414f2015-02-06 15:44:39 -060065 if (ExtractResource(pZip, "images", file, ".png", TMP_RESOURCE_NAME) == 0)
66 {
thatb240f4a2016-03-14 01:21:38 +010067 rc = res_create_surface(TMP_RESOURCE_NAME, surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060068 unlink(TMP_RESOURCE_NAME);
69 }
70 else if (ExtractResource(pZip, "images", file, "", TMP_RESOURCE_NAME) == 0)
71 {
72 // JPG includes the .jpg extension in the filename so extension should be blank
thatb240f4a2016-03-14 01:21:38 +010073 rc = res_create_surface(TMP_RESOURCE_NAME, surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060074 unlink(TMP_RESOURCE_NAME);
75 }
76 else if (!pZip)
77 {
78 // File name in xml may have included .png so try without adding .png
thatb240f4a2016-03-14 01:21:38 +010079 rc = res_create_surface(file.c_str(), surface);
Ethan Yonker63e414f2015-02-06 15:44:39 -060080 }
thatb240f4a2016-03-14 01:21:38 +010081 if (rc != 0)
82 LOGINFO("Failed to load image from %s%s, error %d\n", file.c_str(), pZip ? " (zip)" : "", rc);
Ethan Yonker63e414f2015-02-06 15:44:39 -060083}
84
85void Resource::CheckAndScaleImage(gr_surface source, gr_surface* destination, int retain_aspect)
86{
87 if (!source) {
88 *destination = NULL;
89 return;
90 }
91 if (get_scale_w() != 0 && get_scale_h() != 0) {
92 float scale_w = get_scale_w(), scale_h = get_scale_h();
93 if (retain_aspect) {
94 if (scale_w < scale_h)
95 scale_h = scale_w;
96 else
97 scale_w = scale_h;
98 }
99 if (res_scale_surface(source, destination, scale_w, scale_h)) {
100 LOGINFO("Error scaling image, using regular size.\n");
101 *destination = source;
102 }
103 } else {
104 *destination = source;
105 }
106}
107
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500108FontResource::FontResource(xml_node<>* node, ZipWrap* pZip)
Dees_Troy51a0e822012-09-05 15:24:24 -0400109 : Resource(node, pZip)
110{
Ethan Yonker74db1572015-10-28 12:44:49 -0500111 origFontSize = 0;
112 origFont = NULL;
113 LoadFont(node, pZip);
114}
115
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500116void FontResource::LoadFont(xml_node<>* node, ZipWrap* pZip)
Ethan Yonker74db1572015-10-28 12:44:49 -0500117{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200118 std::string file;
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200119 xml_attribute<>* attr;
Dees_Troy51a0e822012-09-05 15:24:24 -0400120
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200121 mFont = NULL;
122 if (!node)
123 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400124
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200125 attr = node->first_attribute("filename");
126 if (!attr)
127 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400128
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200129 file = attr->value();
130
Matt Mowera8a89d12016-12-30 18:10:37 -0600131 if (file.size() >= 4 && file.compare(file.size()-4, 4, ".ttf") == 0)
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200132 {
Ethan Yonker74db1572015-10-28 12:44:49 -0500133 int font_size = 0;
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200134
Ethan Yonker74db1572015-10-28 12:44:49 -0500135 if (origFontSize != 0) {
136 attr = node->first_attribute("scale");
137 if (attr == NULL)
138 return;
139 font_size = origFontSize * atoi(attr->value()) / 100;
140 } else {
141 attr = node->first_attribute("size");
142 if (attr == NULL)
143 return;
144 font_size = scale_theme_min(atoi(attr->value()));
145 origFontSize = font_size;
146 }
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200147
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200148 int dpi = 300;
149
150 attr = node->first_attribute("dpi");
Matt Mowera8a89d12016-12-30 18:10:37 -0600151 if (attr)
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200152 dpi = atoi(attr->value());
153
thatb240f4a2016-03-14 01:21:38 +0100154 // we can't use TMP_RESOURCE_NAME here because the ttf subsystem is caching the name and scaling needs to reload the font
155 std::string tmpname = "/tmp/" + file;
156 if (ExtractResource(pZip, "fonts", file, "", tmpname) == 0)
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200157 {
thatb240f4a2016-03-14 01:21:38 +0100158 mFont = gr_ttf_loadFont(tmpname.c_str(), font_size, dpi);
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200159 }
160 else
161 {
Dees Troy3454ade2015-01-20 19:21:04 +0000162 file = std::string(TWRES "fonts/") + file;
Ethan Yonker74db1572015-10-28 12:44:49 -0500163 mFont = gr_ttf_loadFont(file.c_str(), font_size, dpi);
Vojtech Bocek76ee9032014-09-07 15:01:56 +0200164 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200165 }
166 else
167 {
Ethan Yonker88037f42015-10-04 22:09:08 -0500168 LOGERR("Non-TTF fonts are no longer supported.\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200169 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400170}
171
Ethan Yonker74db1572015-10-28 12:44:49 -0500172void FontResource::DeleteFont() {
Matt Mowera8a89d12016-12-30 18:10:37 -0600173 if (mFont)
Ethan Yonker74db1572015-10-28 12:44:49 -0500174 gr_ttf_freeFont(mFont);
175 mFont = NULL;
Matt Mowera8a89d12016-12-30 18:10:37 -0600176 if (origFont)
Ethan Yonker74db1572015-10-28 12:44:49 -0500177 gr_ttf_freeFont(origFont);
178 origFont = NULL;
179}
180
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500181void FontResource::Override(xml_node<>* node, ZipWrap* pZip) {
Ethan Yonker74db1572015-10-28 12:44:49 -0500182 if (!origFont) {
183 origFont = mFont;
184 } else if (mFont) {
185 gr_ttf_freeFont(mFont);
186 mFont = NULL;
187 }
188 LoadFont(node, pZip);
189}
190
Dees_Troy51a0e822012-09-05 15:24:24 -0400191FontResource::~FontResource()
192{
Ethan Yonker74db1572015-10-28 12:44:49 -0500193 DeleteFont();
Dees_Troy51a0e822012-09-05 15:24:24 -0400194}
195
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500196ImageResource::ImageResource(xml_node<>* node, ZipWrap* pZip)
Dees_Troy51a0e822012-09-05 15:24:24 -0400197 : Resource(node, pZip)
198{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200199 std::string file;
Ethan Yonker63e414f2015-02-06 15:44:39 -0600200 gr_surface temp_surface = NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400201
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200202 mSurface = NULL;
Ethan Yonker619a7212014-12-03 16:47:37 -0600203 if (!node) {
204 LOGERR("ImageResource node is NULL\n");
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200205 return;
Ethan Yonker619a7212014-12-03 16:47:37 -0600206 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400207
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200208 if (node->first_attribute("filename"))
209 file = node->first_attribute("filename")->value();
Ethan Yonker63e414f2015-02-06 15:44:39 -0600210 else {
211 LOGERR("No filename specified for image resource.\n");
212 return;
213 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400214
that5267a212015-05-06 23:45:57 +0200215 bool retain_aspect = (node->first_attribute("retainaspect") != NULL);
216 // the value does not matter, if retainaspect is present, we assume that we want to retain it
Ethan Yonker63e414f2015-02-06 15:44:39 -0600217 LoadImage(pZip, file, &temp_surface);
218 CheckAndScaleImage(temp_surface, &mSurface, retain_aspect);
Dees_Troy51a0e822012-09-05 15:24:24 -0400219}
220
221ImageResource::~ImageResource()
222{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200223 if (mSurface)
224 res_free_surface(mSurface);
Dees_Troy51a0e822012-09-05 15:24:24 -0400225}
226
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500227AnimationResource::AnimationResource(xml_node<>* node, ZipWrap* pZip)
Dees_Troy51a0e822012-09-05 15:24:24 -0400228 : Resource(node, pZip)
229{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200230 std::string file;
231 int fileNum = 1;
Dees_Troy51a0e822012-09-05 15:24:24 -0400232
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200233 if (!node)
234 return;
Dees_Troy51a0e822012-09-05 15:24:24 -0400235
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200236 if (node->first_attribute("filename"))
237 file = node->first_attribute("filename")->value();
Ethan Yonker63e414f2015-02-06 15:44:39 -0600238 else {
239 LOGERR("No filename specified for image resource.\n");
240 return;
241 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400242
that5267a212015-05-06 23:45:57 +0200243 bool retain_aspect = (node->first_attribute("retainaspect") != NULL);
244 // the value does not matter, if retainaspect is present, we assume that we want to retain it
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200245 for (;;)
246 {
247 std::ostringstream fileName;
248 fileName << file << std::setfill ('0') << std::setw (3) << fileNum;
Dees_Troy51a0e822012-09-05 15:24:24 -0400249
Ethan Yonker63e414f2015-02-06 15:44:39 -0600250 gr_surface surface, temp_surface = NULL;
251 LoadImage(pZip, fileName.str(), &temp_surface);
252 CheckAndScaleImage(temp_surface, &surface, retain_aspect);
253 if (surface) {
254 mSurfaces.push_back(surface);
255 fileNum++;
256 } else
257 break; // Done loading animation images
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200258 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400259}
260
261AnimationResource::~AnimationResource()
262{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200263 std::vector<gr_surface>::iterator it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400264
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200265 for (it = mSurfaces.begin(); it != mSurfaces.end(); ++it)
266 res_free_surface(*it);
267
268 mSurfaces.clear();
Dees_Troy51a0e822012-09-05 15:24:24 -0400269}
270
that74ac6062015-03-04 22:39:34 +0100271FontResource* ResourceManager::FindFont(const std::string& name) const
Dees_Troy51a0e822012-09-05 15:24:24 -0400272{
that74ac6062015-03-04 22:39:34 +0100273 for (std::vector<FontResource*>::const_iterator it = mFonts.begin(); it != mFonts.end(); ++it)
274 if (name == (*it)->GetName())
275 return *it;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200276 return NULL;
Dees_Troy51a0e822012-09-05 15:24:24 -0400277}
278
that74ac6062015-03-04 22:39:34 +0100279ImageResource* ResourceManager::FindImage(const std::string& name) const
Dees_Troy51a0e822012-09-05 15:24:24 -0400280{
that74ac6062015-03-04 22:39:34 +0100281 for (std::vector<ImageResource*>::const_iterator it = mImages.begin(); it != mImages.end(); ++it)
282 if (name == (*it)->GetName())
283 return *it;
284 return NULL;
285}
286
287AnimationResource* ResourceManager::FindAnimation(const std::string& name) const
288{
289 for (std::vector<AnimationResource*>::const_iterator it = mAnimations.begin(); it != mAnimations.end(); ++it)
290 if (name == (*it)->GetName())
291 return *it;
292 return NULL;
293}
294
thatb2e8f672015-03-05 20:25:39 +0100295std::string ResourceManager::FindString(const std::string& name) const
296{
Ethan Yonker74db1572015-10-28 12:44:49 -0500297 if (this != NULL) {
298 std::map<std::string, string_resource_struct>::const_iterator it = mStrings.find(name);
299 if (it != mStrings.end())
300 return it->second.value;
301 LOGERR("String resource '%s' not found. No default value.\n", name.c_str());
302 PageManager::AddStringResource("NO DEFAULT", name, "[" + name + ("]"));
303 } else {
304 LOGINFO("String resources not loaded when looking for '%s'. No default value.\n", name.c_str());
305 }
thatb2e8f672015-03-05 20:25:39 +0100306 return "[" + name + ("]");
307}
308
Ethan Yonker74db1572015-10-28 12:44:49 -0500309std::string ResourceManager::FindString(const std::string& name, const std::string& default_string) const
310{
311 if (this != NULL) {
312 std::map<std::string, string_resource_struct>::const_iterator it = mStrings.find(name);
313 if (it != mStrings.end())
314 return it->second.value;
315 LOGERR("String resource '%s' not found. Using default value.\n", name.c_str());
316 PageManager::AddStringResource("DEFAULT", name, default_string);
317 } else {
318 LOGINFO("String resources not loaded when looking for '%s'. Using default value.\n", name.c_str());
319 }
320 return default_string;
321}
322
323void ResourceManager::DumpStrings() const
324{
325 if (this == NULL) {
326 gui_print("No string resources\n");
327 return;
328 }
329 std::map<std::string, string_resource_struct>::const_iterator it;
330 gui_print("Dumping all strings:\n");
331 for (it = mStrings.begin(); it != mStrings.end(); it++)
332 gui_print("source: %s: '%s' = '%s'\n", it->second.source.c_str(), it->first.c_str(), it->second.value.c_str());
333 gui_print("Done dumping strings\n");
334}
335
that74ac6062015-03-04 22:39:34 +0100336ResourceManager::ResourceManager()
337{
Ethan Yonker780cd392014-07-21 15:24:39 -0500338}
339
Ethan Yonker74db1572015-10-28 12:44:49 -0500340void ResourceManager::AddStringResource(std::string resource_source, std::string resource_name, std::string value)
341{
342 string_resource_struct res;
343 res.source = resource_source;
344 res.value = value;
345 mStrings[resource_name] = res;
346}
347
Ethan Yonker8373cfe2017-09-08 06:50:54 -0500348void ResourceManager::LoadResources(xml_node<>* resList, ZipWrap* pZip, std::string resource_source)
Ethan Yonker780cd392014-07-21 15:24:39 -0500349{
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200350 if (!resList)
351 return;
that0f425062015-03-04 23:05:00 +0100352
353 for (xml_node<>* child = resList->first_node(); child; child = child->next_sibling())
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200354 {
that0f425062015-03-04 23:05:00 +0100355 std::string type = child->name();
356 if (type == "resource") {
357 // legacy format : <resource type="...">
358 xml_attribute<>* attr = child->first_attribute("type");
359 type = attr ? attr->value() : "*unspecified*";
360 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400361
that74ac6062015-03-04 22:39:34 +0100362 bool error = false;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200363 if (type == "font")
364 {
that74ac6062015-03-04 22:39:34 +0100365 FontResource* res = new FontResource(child, pZip);
366 if (res->GetResource())
367 mFonts.push_back(res);
368 else {
369 error = true;
370 delete res;
371 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200372 }
Ethan Yonker74db1572015-10-28 12:44:49 -0500373 else if (type == "fontoverride")
374 {
375 if (mFonts.size() != 0 && child && child->first_attribute("name")) {
376 string FontName = child->first_attribute("name")->value();
377 size_t font_count = mFonts.size(), i;
378 bool found = false;
379
380 for (i = 0; i < font_count; i++) {
381 if (mFonts[i]->GetName() == FontName) {
382 mFonts[i]->Override(child, pZip);
383 found = true;
384 break;
385 }
386 }
387 if (!found) {
388 LOGERR("Unable to locate font '%s' for override.\n", FontName.c_str());
389 }
390 } else if (mFonts.size() != 0)
391 LOGERR("Unable to locate font name for type fontoverride.\n");
392 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200393 else if (type == "image")
394 {
that5267a212015-05-06 23:45:57 +0200395 ImageResource* res = new ImageResource(child, pZip);
that74ac6062015-03-04 22:39:34 +0100396 if (res->GetResource())
397 mImages.push_back(res);
398 else {
399 error = true;
400 delete res;
401 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200402 }
403 else if (type == "animation")
404 {
that5267a212015-05-06 23:45:57 +0200405 AnimationResource* res = new AnimationResource(child, pZip);
that74ac6062015-03-04 22:39:34 +0100406 if (res->GetResourceCount())
407 mAnimations.push_back(res);
408 else {
409 error = true;
410 delete res;
411 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200412 }
thatb2e8f672015-03-05 20:25:39 +0100413 else if (type == "string")
414 {
Ethan Yonker74db1572015-10-28 12:44:49 -0500415 if (xml_attribute<>* attr = child->first_attribute("name")) {
416 string_resource_struct res;
417 res.source = resource_source;
418 res.value = child->value();
419 mStrings[attr->value()] = res;
420 } else
thatb2e8f672015-03-05 20:25:39 +0100421 error = true;
422 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200423 else
424 {
425 LOGERR("Resource type (%s) not supported.\n", type.c_str());
that74ac6062015-03-04 22:39:34 +0100426 error = true;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200427 }
thatf6ed8fc2015-02-14 20:23:16 +0100428
that74ac6062015-03-04 22:39:34 +0100429 if (error)
thatf74ac872015-01-18 12:00:02 +0100430 {
431 std::string res_name;
432 if (child->first_attribute("name"))
433 res_name = child->first_attribute("name")->value();
434 if (res_name.empty() && child->first_attribute("filename"))
435 res_name = child->first_attribute("filename")->value();
436
437 if (!res_name.empty()) {
438 LOGERR("Resource (%s)-(%s) failed to load\n", type.c_str(), res_name.c_str());
439 } else
440 LOGERR("Resource type (%s) failed to load\n", type.c_str());
thatf74ac872015-01-18 12:00:02 +0100441 }
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200442 }
Dees_Troy51a0e822012-09-05 15:24:24 -0400443}
444
445ResourceManager::~ResourceManager()
446{
that74ac6062015-03-04 22:39:34 +0100447 for (std::vector<FontResource*>::iterator it = mFonts.begin(); it != mFonts.end(); ++it)
448 delete *it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400449
that74ac6062015-03-04 22:39:34 +0100450 for (std::vector<ImageResource*>::iterator it = mImages.begin(); it != mImages.end(); ++it)
451 delete *it;
Vojtech Bocekfafb0c52013-07-25 22:53:02 +0200452
that74ac6062015-03-04 22:39:34 +0100453 for (std::vector<AnimationResource*>::iterator it = mAnimations.begin(); it != mAnimations.end(); ++it)
454 delete *it;
Dees_Troy51a0e822012-09-05 15:24:24 -0400455}