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 "common/config-manager.h"
24
25 #include "sludge/cursors.h"
26 #include "sludge/errors.h"
27 #include "sludge/event.h"
28 #include "sludge/fonttext.h"
29 #include "sludge/floor.h"
30 #include "sludge/fileset.h"
31 #include "sludge/function.h"
32 #include "sludge/graphics.h"
33 #include "sludge/imgloader.h"
34 #include "sludge/language.h"
35 #include "sludge/moreio.h"
36 #include "sludge/newfatal.h"
37 #include "sludge/objtypes.h"
38 #include "sludge/people.h"
39 #include "sludge/region.h"
40 #include "sludge/savedata.h"
41 #include "sludge/sludge.h"
42 #include "sludge/sludger.h"
43 #include "sludge/sound.h"
44 #include "sludge/speech.h"
45 #include "sludge/statusba.h"
46 #include "sludge/timing.h"
47 #include "sludge/version.h"
48
49 namespace Sludge {
50
51 extern int numBIFNames;
52 extern Common::String *allBIFNames;
53 extern int numUserFunc;
54 extern Common::String *allUserFunc;
55
56 int selectedLanguage = 0;
57
58 int gameVersion;
59 FILETIME fileTime;
60
61 int numGlobals = 0;
62
63 extern Variable *launchResult;
64 extern Variable *globalVars;
65 extern VariableStack *noStack;
66
67 extern bool allowAnyFilename;
68
openAndVerify(const Common::String & filename,char extra1,char extra2,const char * er,int & fileVersion)69 Common::File *openAndVerify(const Common::String &filename, char extra1, char extra2,
70 const char *er, int &fileVersion) {
71 Common::File *fp = new Common::File();
72 if (!fp->open(filename)) {
73 fatal("Can't open file", filename);
74 return NULL;
75 }
76 bool headerBad = false;
77 if (fp->readByte() != 'S')
78 headerBad = true;
79 if (fp->readByte() != 'L')
80 headerBad = true;
81 if (fp->readByte() != 'U')
82 headerBad = true;
83 if (fp->readByte() != 'D')
84 headerBad = true;
85 if (fp->readByte() != extra1)
86 headerBad = true;
87 if (fp->readByte() != extra2)
88 headerBad = true;
89 if (headerBad) {
90 fatal(er, filename);
91 return NULL;
92 }
93 char c;
94 c = fp->readByte();
95 while ((c = fp->readByte()))
96 ;
97
98 int majVersion = fp->readByte();
99 debugC(2, kSludgeDebugDataLoad, "majVersion %i", majVersion);
100 int minVersion = fp->readByte();
101 debugC(2, kSludgeDebugDataLoad, "minVersion %i", minVersion);
102 fileVersion = majVersion * 256 + minVersion;
103
104 Common::String txtVer = "";
105
106 if (fileVersion > WHOLE_VERSION) {
107 txtVer = Common::String::format(ERROR_VERSION_TOO_LOW_2, majVersion, minVersion);
108 fatal(ERROR_VERSION_TOO_LOW_1, txtVer);
109 return NULL;
110 } else if (fileVersion < MINIM_VERSION) {
111 txtVer = Common::String::format(ERROR_VERSION_TOO_HIGH_2, majVersion, minVersion);
112 fatal(ERROR_VERSION_TOO_HIGH_1, txtVer);
113 return NULL;
114 }
115 return fp;
116 }
117
initSludge()118 void initSludge() {
119 g_sludge->_timer->reset();
120 g_sludge->_languageMan->init();
121 g_sludge->_gfxMan->init();
122 g_sludge->_resMan->init();
123 g_sludge->_peopleMan->init();
124 g_sludge->_floorMan->init();
125 g_sludge->_objMan->init();
126 g_sludge->_speechMan->init();
127 g_sludge->_statusBar->init();
128 g_sludge->_evtMan->init();
129 g_sludge->_txtMan->init();
130 g_sludge->_cursorMan->init();
131
132 g_sludge->_soundMan->init();
133 if (!ConfMan.hasKey("mute") || !ConfMan.getBool("mute")) {
134 g_sludge->_soundMan->initSoundStuff();
135 }
136
137 CustomSaveHelper::_saveEncoding = false;
138
139 // global variables
140 numGlobals = 0;
141 launchResult = nullptr;
142
143 allowAnyFilename = true;
144 noStack = nullptr;
145 numBIFNames = numUserFunc = 0;
146 allUserFunc = allBIFNames = nullptr;
147 }
148
killSludge()149 void killSludge() {
150 killAllFunctions();
151 g_sludge->_speechMan->kill();
152 g_sludge->_peopleMan->kill();
153 g_sludge->_regionMan->kill();
154 g_sludge->_floorMan->kill();
155 g_sludge->_languageMan->kill();
156 g_sludge->_gfxMan->kill();
157 g_sludge->_resMan->kill();
158 g_sludge->_objMan->kill();
159 g_sludge->_soundMan->killSoundStuff();
160 g_sludge->_evtMan->kill();
161 g_sludge->_txtMan->kill();
162 g_sludge->_cursorMan->kill();
163
164 // global variables
165 numBIFNames = numUserFunc = 0;
166 delete []allUserFunc;
167 delete []allBIFNames;
168 }
169
initSludge(const Common::String & filename)170 bool initSludge(const Common::String &filename) {
171 initSludge();
172
173 Common::File *fp = openAndVerify(filename, 'G', 'E', ERROR_BAD_HEADER, gameVersion);
174 if (!fp)
175 return false;
176
177 char c = fp->readByte();
178 if (c) {
179 numBIFNames = fp->readUint16BE();
180 debugC(2, kSludgeDebugDataLoad, "numBIFNames %i", numBIFNames);
181 allBIFNames = new Common::String[numBIFNames];
182 if (!checkNew(allBIFNames))
183 return false;
184
185 for (int fn = 0; fn < numBIFNames; fn++) {
186 allBIFNames[fn].clear();
187 allBIFNames[fn] = readString(fp);
188 }
189 numUserFunc = fp->readUint16BE();
190 debugC(2, kSludgeDebugDataLoad, "numUserFunc %i", numUserFunc);
191 allUserFunc = new Common::String[numUserFunc];
192 if (!checkNew(allUserFunc))
193 return false;
194
195 for (int fn = 0; fn < numUserFunc; fn++) {
196 allUserFunc[fn].clear();
197 allUserFunc[fn] = readString(fp);
198 }
199
200 if (gameVersion >= VERSION(1, 3)) {
201 g_sludge->_resMan->readResourceNames(fp);
202 }
203 }
204
205 int winWidth = fp->readUint16BE();
206 debugC(2, kSludgeDebugDataLoad, "winWidth : %i", winWidth);
207 int winHeight = fp->readUint16BE();
208 debugC(2, kSludgeDebugDataLoad, "winHeight : %i", winHeight);
209 g_sludge->_gfxMan->setWindowSize(winWidth, winHeight);
210
211 int specialSettings = fp->readByte();
212 debugC(2, kSludgeDebugDataLoad, "specialSettings : %i", specialSettings);
213 g_sludge->_timer->setDesiredFPS(1000 / fp->readByte());
214
215 readString(fp); // Unused - was used for registration purposes.
216
217 uint bytes_read = fp->read(&fileTime, sizeof(FILETIME));
218 if (bytes_read != sizeof(FILETIME) && fp->err()) {
219 debug(0, "Reading error in initSludge.");
220 }
221
222 Common::String dataFol = (gameVersion >= VERSION(1, 3)) ? readString(fp) : "";
223 debugC(2, kSludgeDebugDataLoad, "dataFol : %s", dataFol.c_str());
224
225 g_sludge->_languageMan->createTable(fp);
226
227 if (gameVersion >= VERSION(1, 6)) {
228 fp->readByte();
229 // aaLoad
230 fp->readByte();
231 fp->readFloatLE();
232 fp->readFloatLE();
233 }
234
235 Common::String checker = readString(fp);
236 debugC(2, kSludgeDebugDataLoad, "checker : %s", checker.c_str());
237
238 if (checker != "okSoFar")
239 return fatal(ERROR_BAD_HEADER, filename);
240
241 byte customIconLogo = fp->readByte();
242 debugC(2, kSludgeDebugDataLoad, "Game icon type: %i", customIconLogo);
243
244 if (customIconLogo & 1) {
245 // There is an icon - read it!
246 debugC(2, kSludgeDebugDataLoad, "There is an icon - read it!");
247
248 // read game icon
249 Graphics::Surface gameIcon;
250 if (!ImgLoader::loadImage(-1, "icon", fp, &gameIcon, false))
251 return false;
252
253 }
254
255 if (customIconLogo & 2) {
256 // There is an logo - read it!
257 debugC(2, kSludgeDebugDataLoad, "There is an logo - read it!");
258
259 // read game logo
260 Graphics::Surface gameLogo;
261 if (!ImgLoader::loadImage(-1, "logo", fp, &gameLogo))
262 return false;
263 }
264
265 numGlobals = fp->readUint16BE();
266 debugC(2, kSludgeDebugDataLoad, "numGlobals : %i", numGlobals);
267
268 globalVars = new Variable[numGlobals];
269 if (!checkNew(globalVars))
270 return false;
271
272 // Get language selected by user
273 g_sludge->_resMan->setData(fp);
274 g_sludge->_languageMan->setLanguageID(g_sludge->getLanguageID());
275
276 if (!dataFol.empty()) {
277 Common::String dataFolder = encodeFilename(dataFol);
278 }
279
280 g_sludge->_statusBar->positionStatus(10, winHeight - 15);
281
282 return true;
283 }
284
displayBase()285 void displayBase() {
286 g_sludge->_gfxMan->clear(); // Clear screen
287 g_sludge->_gfxMan->drawBackDrop();// Draw Backdrop
288 g_sludge->_gfxMan->drawZBuffer(g_sludge->_gfxMan->getCamX(), g_sludge->_gfxMan->getCamY(), false);
289 g_sludge->_peopleMan->drawPeople();// Then add any moving characters...
290 g_sludge->_gfxMan->displaySpriteLayers();
291 }
292
sludgeDisplay()293 void sludgeDisplay() {
294 displayBase();
295 g_sludge->_speechMan->display();
296 g_sludge->_statusBar->draw();
297 g_sludge->_cursorMan->displayCursor();
298 g_sludge->_gfxMan->display();
299 }
300
301 } // End of namespace Sludge
302