1 /* ScummVM - Graphic Adventure Engine
2 *
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 */
22
23 #include "titanic/core/project_item.h"
24 #include "titanic/events.h"
25 #include "titanic/support/simple_file.h"
26 #include "titanic/titanic.h"
27 #include "base/plugins.h"
28 #include "common/savefile.h"
29 #include "common/str-array.h"
30 #include "common/memstream.h"
31 #include "engines/advancedDetector.h"
32 #include "common/system.h"
33 #include "graphics/colormasks.h"
34 #include "graphics/surface.h"
35
36 namespace Titanic {
37
38 struct TitanicGameDescription {
39 ADGameDescription desc;
40 };
41
getFeatures() const42 uint32 TitanicEngine::getFeatures() const {
43 return _gameDescription->desc.flags;
44 }
45
getLanguage() const46 Common::Language TitanicEngine::getLanguage() const {
47 return _gameDescription->desc.language;
48 }
49
50 } // End of namespace Titanic
51
52 static const PlainGameDescriptor TitanicGames[] = {
53 {"titanic", "Starship Titanic"},
54 {0, 0}
55 };
56
57 #include "titanic/detection_tables.h"
58
59 class TitanicMetaEngine : public AdvancedMetaEngine {
60 public:
TitanicMetaEngine()61 TitanicMetaEngine() : AdvancedMetaEngine(Titanic::gameDescriptions, sizeof(Titanic::TitanicGameDescription), TitanicGames) {
62 _maxScanDepth = 3;
63 }
64
getName() const65 virtual const char *getName() const {
66 return "Starship Titanic";
67 }
68
getOriginalCopyright() const69 virtual const char *getOriginalCopyright() const {
70 return "Starship Titanic (C) The Digital Village";
71 }
72
73 virtual bool hasFeature(MetaEngineFeature f) const;
74 virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
75 virtual SaveStateList listSaves(const char *target) const;
76 virtual int getMaximumSaveSlot() const;
77 virtual void removeSaveState(const char *target, int slot) const;
78 SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
79 };
80
hasFeature(MetaEngineFeature f) const81 bool TitanicMetaEngine::hasFeature(MetaEngineFeature f) const {
82 return
83 (f == kSupportsListSaves) ||
84 (f == kSupportsLoadingDuringStartup) ||
85 (f == kSupportsDeleteSave) ||
86 (f == kSavesSupportMetaInfo) ||
87 (f == kSavesSupportCreationDate) ||
88 (f == kSavesSupportPlayTime) ||
89 (f == kSavesSupportThumbnail) ||
90 (f == kSimpleSavesNames);
91 }
92
hasFeature(EngineFeature f) const93 bool Titanic::TitanicEngine::hasFeature(EngineFeature f) const {
94 return
95 (f == kSupportsRTL) ||
96 (f == kSupportsLoadingDuringRuntime) ||
97 (f == kSupportsSavingDuringRuntime);
98 }
99
createInstance(OSystem * syst,Engine ** engine,const ADGameDescription * desc) const100 bool TitanicMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
101 const Titanic::TitanicGameDescription *gd = (const Titanic::TitanicGameDescription *)desc;
102 *engine = new Titanic::TitanicEngine(syst, gd);
103
104 return gd != 0;
105 }
106
listSaves(const char * target) const107 SaveStateList TitanicMetaEngine::listSaves(const char *target) const {
108 Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
109 Common::StringArray filenames;
110 Common::String saveDesc;
111 Common::String pattern = Common::String::format("%s.0##", target);
112 Titanic::TitanicSavegameHeader header;
113
114 filenames = saveFileMan->listSavefiles(pattern);
115
116 SaveStateList saveList;
117 for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
118 const char *ext = strrchr(file->c_str(), '.');
119 int slot = ext ? atoi(ext + 1) : -1;
120
121 if (slot >= 0 && slot <= MAX_SAVES) {
122 Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file);
123
124 if (in) {
125 Titanic::CompressedFile cf;
126 cf.open(in);
127
128 if (Titanic::CProjectItem::readSavegameHeader(&cf, header))
129 saveList.push_back(SaveStateDescriptor(slot, header._saveName));
130
131 cf.close();
132 }
133 }
134 }
135
136 // Sort saves based on slot number.
137 Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
138 return saveList;
139 }
140
getMaximumSaveSlot() const141 int TitanicMetaEngine::getMaximumSaveSlot() const {
142 return MAX_SAVES;
143 }
144
removeSaveState(const char * target,int slot) const145 void TitanicMetaEngine::removeSaveState(const char *target, int slot) const {
146 Common::String filename = Common::String::format("%s.%03d", target, slot);
147 g_system->getSavefileManager()->removeSavefile(filename);
148 }
149
querySaveMetaInfos(const char * target,int slot) const150 SaveStateDescriptor TitanicMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
151 Common::String filename = Common::String::format("%s.%03d", target, slot);
152 Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename);
153
154 if (f) {
155 Titanic::CompressedFile file;
156 file.open(f);
157
158 Titanic::TitanicSavegameHeader header;
159 if (!Titanic::CProjectItem::readSavegameHeader(&file, header, false)) {
160 file.close();
161 return SaveStateDescriptor();
162 }
163
164 file.close();
165
166 // Create the return descriptor
167 SaveStateDescriptor desc(slot, header._saveName);
168
169 if (header._version) {
170 desc.setThumbnail(header._thumbnail);
171 desc.setSaveDate(header._year, header._month, header._day);
172 desc.setSaveTime(header._hour, header._minute);
173 desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME);
174 }
175
176 return desc;
177 }
178
179 return SaveStateDescriptor();
180 }
181
182
183 #if PLUGIN_ENABLED_DYNAMIC(TITANIC)
184 REGISTER_PLUGIN_DYNAMIC(TITANIC, PLUGIN_TYPE_ENGINE, TitanicMetaEngine);
185 #else
186 REGISTER_PLUGIN_STATIC(TITANIC, PLUGIN_TYPE_ENGINE, TitanicMetaEngine);
187 #endif
188