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