Ticket #8775: saves.patch
File saves.patch, 23.7 KB (added by , 17 years ago) |
---|
-
engines/sword1/sword1.cpp
169 169 return kNoError; 170 170 } 171 171 172 static SaveStateList Engine_SWORD1_listSaves(const char *target) { 173 return SaveStateList(); 174 } 175 172 176 REGISTER_PLUGIN(SWORD1, "Broken Sword", "Broken Sword Games (C) Revolution"); 173 177 174 178 namespace Sword1 { -
engines/sword2/sword2.cpp
162 162 return kNoGameDataFoundError; 163 163 } 164 164 165 static SaveStateList Engine_SWORD2_listSaves(const char *target) { 166 return SaveStateList(); 167 } 168 165 169 REGISTER_PLUGIN(SWORD2, "Broken Sword 2", "Broken Sword Games (C) Revolution"); 166 170 167 171 namespace Sword2 { -
engines/scumm/dialogs.cpp
421 421 Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode) { 422 422 // Get savegame descriptions 423 423 Common::StringList descriptions; 424 char name[32];425 424 uint i = saveMode ? 1 : 0; //the autosave is on slot #0 426 425 bool avail_saves[81]; 427 426 428 427 scumm->listSavegames(avail_saves, ARRAYSIZE(avail_saves)); 429 428 for (; i < ARRAYSIZE(avail_saves); i++) { 429 Common::String name; 430 430 if (avail_saves[i]) 431 431 scumm->getSavegameName(i, name); 432 else433 name[0] = 0;434 432 descriptions.push_back(name); 435 433 } 436 434 -
engines/scumm/scumm.h
623 623 int getKeyState(int key); 624 624 625 625 public: 626 bool getSavegameName(int slot, char *desc);626 bool getSavegameName(int slot, Common::String &desc); 627 627 void listSavegames(bool *marks, int num); 628 628 629 629 void requestSave(int slot, const char *name, bool temporary = false); -
engines/scumm/saveload.cpp
431 431 } 432 432 } 433 433 434 bool ScummEngine::getSavegameName(int slot, char *desc) { 434 bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion); 435 436 bool ScummEngine::getSavegameName(int slot, Common::String &desc) { 437 Common::InSaveFile *in = 0; 438 bool result = false; 435 439 char filename[256]; 436 Common::InSaveFile *in;437 SaveGameHeader hdr;438 440 441 desc.clear(); 439 442 makeSavegameName(filename, slot, false); 440 if (!(in = _saveFileMan->openForLoading(filename))) { 441 strcpy(desc, ""); 442 return false; 443 in = _saveFileMan->openForLoading(filename); 444 if (in) { 445 result = Scumm::getSavegameName(in, desc, _game.heversion); 446 delete in; 443 447 } 448 return result; 449 } 444 450 451 bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion) { 452 SaveGameHeader hdr; 453 445 454 if (!loadSaveGameHeader(in, hdr)) { 446 delete in; 447 strcpy(desc, "Invalid savegame"); 455 desc = "Invalid savegame"; 448 456 return false; 449 457 } 450 delete in;451 458 452 459 if (hdr.ver > CURRENT_VER) 453 460 hdr.ver = TO_LE_32(hdr.ver); 454 461 if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER) { 455 strcpy(desc, "Invalid version");462 desc = "Invalid version"; 456 463 return false; 457 464 } 458 465 459 466 // We (deliberately) broke HE savegame compatibility at some point. 460 if (hdr.ver < VER(57) && _game.heversion >= 60) {461 strcpy(desc, "Unsupported version");467 if (hdr.ver < VER(57) && heversion >= 60) { 468 desc = "Unsupported version"; 462 469 return false; 463 470 } 464 471 465 memcpy(desc, hdr.name, sizeof(hdr.name));466 desc [sizeof(hdr.name) - 1] = 0;472 hdr.name[sizeof(hdr.name) - 1] = 0; 473 desc = hdr.name; 467 474 return true; 468 475 } 469 476 -
engines/scumm/script_v5.cpp
942 942 int slotSize; 943 943 byte* slotContent; 944 944 int savegameId; 945 char name[32];946 945 bool avail_saves[100]; 947 946 948 947 if (a == STRINGID_IQ_SERIES && b == STRINGID_IQ_SERIES) { … … 960 959 961 960 // load savegame names 962 961 savegameId = slot - a + 1; 962 Common::String name; 963 963 if (avail_saves[savegameId] && getSavegameName(savegameId, name)) { 964 964 int pos; 965 c har *ptr = name;965 const char *ptr = name.c_str(); 966 966 // slotContent ends with {'\0','@'} -> max. length = slotSize-2 967 967 for (pos = 0; pos < slotSize - 2; ++pos) { 968 968 if (!ptr[pos]) -
engines/scumm/detection.cpp
29 29 #include "common/fs.h" 30 30 #include "common/list.h" 31 31 #include "common/md5.h" 32 #include "common/savefile.h" 33 #include "common/system.h" 32 34 33 35 #include "scumm/detection.h" 34 36 #include "scumm/detection_tables.h" … … 904 906 return kNoError; 905 907 } 906 908 909 namespace Scumm { 910 extern bool getSavegameName(Common::InSaveFile *in, Common::String &desc, int heversion); 911 } 912 913 static SaveStateList Engine_SCUMM_listSaves(const char *target) { 914 Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); 915 Common::StringList filenames; 916 Common::String saveDesc; 917 Common::String pattern = target; 918 pattern += ".s??"; 919 920 filenames = saveFileMan->listSavefiles(pattern.c_str()); 921 sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..) 922 923 SaveStateList saveList; 924 for (Common::StringList::const_iterator file = filenames.begin(); file != filenames.end(); file++){ 925 // Obtain the last 2 digits of the filename, since they correspond to the save slot 926 int slotNum = atoi(file->c_str() + file->size() - 2); 927 928 if (slotNum >= 0 && slotNum <= 99) { 929 Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str()); 930 if (in) { 931 Scumm::getSavegameName(in, saveDesc, 0); // FIXME: heversion?!? 932 saveList.push_back(SaveStateDescriptor(slotNum, saveDesc)); 933 delete in; 934 } 935 } 936 } 937 938 return saveList; 939 } 940 907 941 REGISTER_PLUGIN(SCUMM, "Scumm Engine", 908 942 "LucasArts SCUMM Games (C) LucasArts\n" 909 943 "Humongous SCUMM Games (C) Humongous" ); -
engines/scumm/script_v8.cpp
1235 1235 removeBlastTexts(); 1236 1236 break; 1237 1237 case 25: { // saveGameReadName 1238 char name[30];1238 Common::String name; 1239 1239 if (getSavegameName(args[1], name)) { 1240 int size = resStrLen((const byte *)name) + 1;1240 int size = name.size() + 1; 1241 1241 _res->nukeResource(rtString, args[2]); 1242 1242 1243 1243 ArrayHeader *ah = (ArrayHeader *)_res->createResource(rtString, args[2], size + sizeof(ArrayHeader)); … … 1245 1245 ah->dim1 = TO_LE_16(size + 1); 1246 1246 ah->dim2 = TO_LE_16(1); 1247 1247 1248 memcpy(getStringAddress(args[2]), name , size);1248 memcpy(getStringAddress(args[2]), name.c_str(), size); 1249 1249 } 1250 1250 break; 1251 1251 } -
engines/touche/detection.cpp
132 132 return gd != 0; 133 133 } 134 134 135 static SaveStateList Engine_TOUCHE_listSaves(const char *target) { 136 return SaveStateList(); 137 } 138 135 139 ADVANCED_DETECTOR_DEFINE_PLUGIN(TOUCHE, Engine_TOUCHE_createInstance, detectionParams); 136 140 137 141 REGISTER_PLUGIN(TOUCHE, "Touche Engine", "Touche: The Adventures of the 5th Musketeer (C) Clipper Software"); -
engines/agos/detection.cpp
136 136 return res; 137 137 } 138 138 139 static SaveStateList Engine_AGOS_listSaves(const char *target) { 140 return SaveStateList(); 141 } 142 139 143 ADVANCED_DETECTOR_DEFINE_PLUGIN(AGOS, engineCreateAgos, detectionParams); 140 144 141 145 REGISTER_PLUGIN(AGOS, "AGOS", "AGOS (C) Adventure Soft"); -
engines/cruise/detection.cpp
131 131 return gd != 0; 132 132 } 133 133 134 static SaveStateList Engine_CRUISE_listSaves(const char *target) { 135 return SaveStateList(); 136 } 137 134 138 ADVANCED_DETECTOR_DEFINE_PLUGIN(CRUISE, Engine_CRUISE_createInstance, detectionParams); 135 139 136 140 REGISTER_PLUGIN(CRUISE, "Cinematique evo 2 engine", "Cruise for a Corpse (C) Delphine Software"); -
engines/drascula/detection.cpp
171 171 return gd != 0; 172 172 } 173 173 174 static SaveStateList Engine_DRASCULA_listSaves(const char *target) { 175 return SaveStateList(); 176 } 177 174 178 ADVANCED_DETECTOR_DEFINE_PLUGIN(DRASCULA, Engine_DRASCULA_createInstance, detectionParams); 175 179 176 180 REGISTER_PLUGIN(DRASCULA, "Drascula Engine", "Drascula Engine (C) 2000 Alcachofa Soft, 1996 (C) Digital Dreams Multimedia, 1994 (C) Emilio de Paz"); -
engines/igor/detection.cpp
119 119 return gd != 0; 120 120 } 121 121 122 static SaveStateList Engine_IGOR_listSaves(const char *target) { 123 return SaveStateList(); 124 } 125 122 126 ADVANCED_DETECTOR_DEFINE_PLUGIN(IGOR, Engine_IGOR_createInstance, igorDetectionParams); 123 127 124 128 REGISTER_PLUGIN(IGOR, "Igor: Objective Uikokahonia", "Igor: Objective Uikokahonia (C) Pendulo Studios"); -
engines/agi/detection.cpp
2271 2271 return res; 2272 2272 } 2273 2273 2274 static SaveStateList Engine_AGI_listSaves(const char *target) { 2275 return SaveStateList(); 2276 } 2277 2274 2278 ADVANCED_DETECTOR_DEFINE_PLUGIN(AGI, engineCreateAgi, detectionParams); 2275 2279 2276 2280 REGISTER_PLUGIN(AGI, "AGI preAGI + v2 + v3 Engine", "Sierra AGI Engine (C) Sierra On-Line Software"); -
engines/sky/sky.cpp
172 172 return kNoError; 173 173 } 174 174 175 static SaveStateList Engine_SKY_listSaves(const char *target) { 176 return SaveStateList(); 177 } 178 175 179 REGISTER_PLUGIN(SKY, "Beneath a Steel Sky", "Beneath a Steel Sky (C) Revolution"); 176 180 177 181 -
engines/kyra/detection.cpp
469 469 return res; 470 470 } 471 471 472 static SaveStateList Engine_KYRA_listSaves(const char *target) { 473 return SaveStateList(); 474 } 475 472 476 ADVANCED_DETECTOR_DEFINE_PLUGIN(KYRA, engineCreateKyra, detectionParams); 473 477 474 478 REGISTER_PLUGIN(KYRA, "Legend of Kyrandia Engine", "The Legend of Kyrandia (C) Westwood Studios"); -
engines/lure/detection.cpp
182 182 return gd != 0; 183 183 } 184 184 185 static SaveStateList Engine_LURE_listSaves(const char *target) { 186 return SaveStateList(); 187 } 188 185 189 ADVANCED_DETECTOR_DEFINE_PLUGIN(LURE, Engine_LURE_createInstance, detectionParams); 186 190 187 191 REGISTER_PLUGIN(LURE, "Lure of the Temptress Engine", "Lure of the Temptress (C) Revolution"); -
engines/gob/detection.cpp
1751 1751 return gd != 0; 1752 1752 } 1753 1753 1754 static SaveStateList Engine_GOB_listSaves(const char *target) { 1755 return SaveStateList(); 1756 } 1757 1754 1758 ADVANCED_DETECTOR_DEFINE_PLUGIN(GOB, Engine_GOB_createInstance, detectionParams); 1755 1759 1756 1760 REGISTER_PLUGIN(GOB, "Gob Engine", "Goblins Games (C) Coktel Vision"); -
engines/parallaction/detection.cpp
203 203 return res; 204 204 } 205 205 206 static SaveStateList Engine_PARALLACTION_listSaves(const char *target) { 207 return SaveStateList(); 208 } 209 206 210 ADVANCED_DETECTOR_DEFINE_PLUGIN(PARALLACTION, Engine_PARALLACTION_createInstance, detectionParams); 207 211 208 212 REGISTER_PLUGIN(PARALLACTION, "Parallaction engine", "Nippon Safes Inc. (C) Dynabyte"); -
engines/saga/detection.cpp
147 147 return gd != 0; 148 148 } 149 149 150 static SaveStateList Engine_SAGA_listSaves(const char *target) { 151 return SaveStateList(); 152 } 153 150 154 ADVANCED_DETECTOR_DEFINE_PLUGIN(SAGA, Engine_SAGA_createInstance, detectionParams); 151 155 152 156 REGISTER_PLUGIN(SAGA, "SAGA Engine", "Inherit the Earth (C) Wyrmkeep Entertainment"); -
engines/queen/queen.cpp
105 105 return kNoError; 106 106 } 107 107 108 static SaveStateList Engine_QUEEN_listSaves(const char *target) { 109 return SaveStateList(); 110 } 111 108 112 REGISTER_PLUGIN(QUEEN, "Flight of the Amazon Queen", "Flight of the Amazon Queen (C) John Passfield and Steve Stamatiadis"); 109 113 110 114 namespace Queen { -
engines/cine/detection.cpp
496 496 return gd != 0; 497 497 } 498 498 499 static SaveStateList Engine_CINE_listSaves(const char *target) { 500 return SaveStateList(); 501 } 502 499 503 ADVANCED_DETECTOR_DEFINE_PLUGIN(CINE, Engine_CINE_createInstance, detectionParams); 500 504 501 505 REGISTER_PLUGIN(CINE, "Cinematique evo 1 engine", "Future Wars & Operation Stealth (C) Delphine Software"); -
backends/plugins/dynamic-plugin.h
36 36 typedef GameDescriptor (*GameIDQueryFunc)(const char *gameid); 37 37 typedef GameList (*GameIDListFunc)(); 38 38 typedef GameList (*DetectFunc)(const FSList &fslist); 39 typedef SaveStateList (*ListSavesFunc)(const char *target); 39 40 40 41 41 42 class DynamicPlugin : public Plugin { … … 47 48 GameIDQueryFunc _qf; 48 49 EngineFactory _ef; 49 50 DetectFunc _df; 51 ListSavesFunc _lsf; 50 52 GameList _games; 51 53 54 // FIXME: We should really split the ScummVM engine plugin specific stuff 55 // into a separate class and keep only the findSymbol function... 52 56 virtual VoidFunc findSymbol(const char *symbol) = 0; 53 57 54 58 public: 55 DynamicPlugin() : _qf(0), _ef(0), _df(0), _ games() {}59 DynamicPlugin() : _qf(0), _ef(0), _df(0), _lsf(0), _games() {} 56 60 57 61 const char *getName() const { return _name.c_str(); } 58 62 const char *getCopyright() const { return _copyright.c_str(); } … … 74 78 return (*_df)(fslist); 75 79 } 76 80 81 82 SaveStateList listSaves(const char *target) const { 83 assert(_lsf); 84 return (*_lsf)(fslist); 85 } 86 77 87 virtual bool loadPlugin() { 78 88 // Query the plugin's name 79 89 NameFunc nameFunc = (NameFunc)findSymbol("PLUGIN_name"); -
base/game.h
30 30 #include "common/array.h" 31 31 #include "common/hash-str.h" 32 32 33 namespace Graphics { 34 class Surface; 35 } 36 33 37 /** 34 38 * A simple structure used to map gameids (like "monkey", "sword1", ...) to 35 39 * nice human readable and descriptive game titles (like "The Secret of Monkey Island"). … … 67 71 setVal("description", pgd.description); 68 72 } 69 73 70 GameDescriptor( Common::String g, Common::Stringd, Common::Language l = Common::UNK_LANG,74 GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l = Common::UNK_LANG, 71 75 Common::Platform p = Common::kPlatformUnknown) { 72 76 setVal("gameid", g); 73 77 setVal("description", d); … … 103 107 } 104 108 }; 105 109 110 /** 111 * A hashmap describing details about a given save state. 112 * TODO 113 * Guaranteed to contain save_slot and description values. 114 * Additional ideas: Playtime, creation date, thumbnail, ... 115 */ 116 class SaveStateDescriptor : public Common::StringMap { 117 protected: 118 Graphics::Surface *_thumbnail; // can be NULL 119 public: 120 SaveStateDescriptor() : _thumbnail(0) { 121 setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ? 122 setVal("description", ""); 123 } 106 124 125 SaveStateDescriptor(int s, const Common::String &d) : _thumbnail(0) { 126 char buf[16]; 127 sprintf(buf, "%d", s); 128 setVal("save_slot", buf); 129 setVal("description", d); 130 } 107 131 132 SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail(0) { 133 setVal("save_slot", s); 134 setVal("description", d); 135 } 136 137 ~SaveStateDescriptor() { 138 setThumbnail(0); 139 } 140 141 /** The saveslot id, as it would be passed to the "-x" command line switch. */ 142 Common::String &slot() { return getVal("save_slot"); } 143 144 /** The saveslot id, as it would be passed to the "-x" command line switch (read-only variant). */ 145 const Common::String &slot() const { return getVal("save_slot"); } 146 147 /** A human readable description of the save state. */ 148 Common::String &description() { return getVal("description"); } 149 150 /** A human readable description of the save state (read-only variant). */ 151 const Common::String &description() const { return getVal("description"); } 152 153 /** 154 * Return a thumbnail graphics surface representing the savestate visually 155 * This is usually a scaled down version of the game graphics. The size 156 * should be either 160x100 or 160x120 pixels, depending on the aspect 157 * ratio of the game. If another ratio is required, contact the core team. 158 * 159 * TODO: it is probably a bad idea to read this for *all* games at once, 160 * at least on low-end devices. So this info should probably normally only 161 * be included optionally. I.e. only upon a query for a specific savegame... 162 * To this end, add a getFullSaveStateInfo(target, slot) to the plugin API. 163 */ 164 const Graphics::Surface *getThumbnail() const { return _thumbnail; } 165 166 167 void setThumbnail(Graphics::Surface *t); 168 }; 169 170 /** List of savestates. */ 171 typedef Common::Array<SaveStateDescriptor> SaveStateList; 172 173 108 174 class Plugin; 109 175 110 176 namespace Base { -
base/plugins.cpp
62 62 assert(_plugin->_df); 63 63 return (*_plugin->_df)(fslist); 64 64 } 65 66 SaveStateList listSaves(const char *target) const { 67 assert(_plugin->_lsf); 68 return (*_plugin->_lsf)(target); 69 } 65 70 }; 66 71 67 72 class StaticPluginProvider : public PluginProvider { -
base/plugins.h
59 59 public: 60 60 virtual ~Plugin() {} 61 61 62 // virtual bool isLoaded() const = 0; // TODO 62 63 virtual bool loadPlugin() = 0; 63 64 virtual void unloadPlugin() = 0; 64 65 … … 70 71 virtual GameDescriptor findGame(const char *gameid) const = 0; 71 72 virtual GameList detectGames(const FSList &fslist) const = 0; 72 73 74 virtual SaveStateList listSaves(const char *target) const = 0; 75 73 76 virtual PluginError createInstance(OSystem *syst, Engine **engine) const = 0; 74 77 }; 75 78 … … 106 109 Engine_##ID##_gameIDList(), \ 107 110 Engine_##ID##_findGameID, \ 108 111 Engine_##ID##_create, \ 109 Engine_##ID##_detectGames \ 112 Engine_##ID##_detectGames, \ 113 Engine_##ID##_listSaves \ 110 114 );\ 111 115 } \ 112 116 void dummyFuncToAllowTrailingSemicolon() … … 119 123 PLUGIN_EXPORT GameDescriptor PLUGIN_findGameID(const char *gameid) { return Engine_##ID##_findGameID(gameid); } \ 120 124 PLUGIN_EXPORT PluginError PLUGIN_createEngine(OSystem *syst, Engine **engine) { return Engine_##ID##_create(syst, engine); } \ 121 125 PLUGIN_EXPORT GameList PLUGIN_detectGames(const FSList &fslist) { return Engine_##ID##_detectGames(fslist); } \ 126 PLUGIN_EXPORT SaveStateList PLUGIN_listSaves(const char *target) { return Engine_##ID##_listSaves(target); } \ 122 127 } \ 123 128 void dummyFuncToAllowTrailingSemicolon() 124 129 #endif … … 134 139 typedef GameDescriptor (*GameIDQueryFunc)(const char *gameid); 135 140 typedef PluginError (*EngineFactory)(OSystem *syst, Engine **engine); 136 141 typedef GameList (*DetectFunc)(const FSList &fslist); 142 typedef SaveStateList (*ListSavesFunc)(const char *target); 137 143 138 144 protected: 139 145 const char *_name; … … 141 147 GameIDQueryFunc _qf; 142 148 EngineFactory _ef; 143 149 DetectFunc _df; 150 ListSavesFunc _lsf; 144 151 GameList _games; 145 152 146 153 public: 147 PluginRegistrator(const char *name, const char *copyright, GameList games, GameIDQueryFunc qf, EngineFactory ef, DetectFunc df )148 : _name(name), _copyright(copyright), _qf(qf), _ef(ef), _df(df), _ games(games) {}154 PluginRegistrator(const char *name, const char *copyright, GameList games, GameIDQueryFunc qf, EngineFactory ef, DetectFunc df, ListSavesFunc lsf) 155 : _name(name), _copyright(copyright), _qf(qf), _ef(ef), _df(df), _lsf(lsf), _games(games) {} 149 156 }; 150 157 #endif 151 158 -
base/commandLine.cpp
567 567 printf("Target Description \n" 568 568 "-------------------- ------------------------------------------------------\n"); 569 569 570 #if 1 571 // FIXME HACK 572 g_system->initBackend(); 573 #endif 574 570 575 using namespace Common; 571 576 const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); 572 ConfigManager::DomainMap::const_iterator iter = domains.begin();577 ConfigManager::DomainMap::const_iterator iter; 573 578 for (iter = domains.begin(); iter != domains.end(); ++iter) { 574 579 Common::String name(iter->_key); 575 580 Common::String description(iter->_value.get("description")); … … 585 590 } 586 591 587 592 printf("%-20s %s\n", name.c_str(), description.c_str()); 593 594 #if 1 595 // FIXME HACK: List all savegames for that target 596 597 // Grab the gameid from the domain 598 Common::String gameid(iter->_value.get("gameid")); 599 if (gameid.empty()) 600 gameid = name; 601 gameid.toLowercase(); 602 603 // Find the plugin that will handle the specified gameid 604 const Plugin *plugin = 0; 605 GameDescriptor game = Base::findGame(gameid, &plugin); 606 607 if (!plugin) 608 continue; 609 610 // Query the plugin for a list of savegames 611 SaveStateList saveList = plugin->listSaves(name.c_str()); 612 613 //saveList = FOO; 614 if (!saveList.empty()) { 615 printf(" Saves:\n"); 616 for (SaveStateList::const_iterator x = saveList.begin(); x != saveList.end(); ++x) { 617 printf(" slot %-4s %s\n", x->slot().c_str(), x->description().c_str()); 618 // TODO: Could also iterate over the full hashmap, printing all key-value pairs 619 } 620 } 621 #endif 588 622 } 589 623 } 590 624 -
base/game.cpp
25 25 26 26 #include "base/game.h" 27 27 #include "base/plugins.h" 28 #include "graphics/surface.h" 28 29 30 29 31 const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) { 30 32 const PlainGameDescriptor *g = list; 31 33 while (g->gameid) { … … 66 68 } 67 69 } 68 70 71 void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) { 72 if (_thumbnail && _thumbnail != t) { 73 _thumbnail->free(); 74 delete _thumbnail; 75 } 76 _thumbnail = t; 77 } 78 79 69 80 namespace Base { 70 81 71 82 // TODO: Find a better name & place for this function.