1 /*
2 Copyright (C) 2004 Parallel Realities
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 
21 #include "init.h"
22 
23 /*
24 Show the GNU Public License the first time the game is played. Waits 4 seconds
25 and then proceeds. THIS MUST NOT BE REMOVED!!!!!
26 */
showLicense()27 void showLicense()
28 {
29 	graphics.clearScreen(graphics.black);
30 	graphics.delay(1000);
31 
32 	SDL_Surface *pic = graphics.loadImage("gfx/main/licensePic.png");
33 	graphics.blit(pic, 0, 0, graphics.screen, false);
34 	graphics.fade(185);
35 	SDL_FreeSurface(pic);
36 
37 	engine.loadData("data/LICENSE");
38 
39 	char line[255];
40 	int y = 0;
41 
42 	char *token = strtok((char*)engine.dataBuffer, "\n");
43 
44 	graphics.setFontSize(1);
45 
46 	while (true)
47 	{
48 		sscanf(token, "%d %[^\n]", &y, line);
49 
50 		graphics.drawString(400, y, true, graphics.screen, line);
51 
52 		token = strtok(NULL, "\n");
53 
54 		if (token == NULL)
55 			break;
56 	}
57 
58 	graphics.delay(4000);
59 
60 	graphics.drawString(400, 540, true, graphics.screen, "Press Space to Continue...");
61 
62 	engine.flushInput();
63 	engine.clearInput();
64 
65 	while (true)
66 	{
67 		graphics.updateScreen();
68 		engine.getInput();
69 		if (engine.keyState[SDLK_SPACE])
70 			break;
71 	}
72 
73 	graphics.clearScreen(graphics.black);
74 	graphics.delay(500);
75 }
76 
77 /*
78 This bit is just for Linux and Unix users. It attempts to get the user's
79 home directory, then creates the .parallelrealities and .parallelrealities/q
80 directories so that saves and temporary data files can be written there. Good, eh? :)
81 */
82 #if UNIX
setupUserHomeDirectory()83 void setupUserHomeDirectory()
84 {
85 	char *userHome;
86 
87 	char *name = getlogin();
88 
89 	passwd *pass;
90 
91 	if (name != NULL)
92 		pass = getpwnam(name);
93 	else
94 		pass = getpwuid(geteuid());
95 
96 	if (pass == NULL)
97 	{
98 		printf("Couldn't determine the user home directory. Exitting.\n");
99 		exit(1);
100 	}
101 
102 	userHome = pass->pw_dir;
103 
104 	strcpy(gameData.directorySearchPath, userHome);
105 
106 	debug(("User Home Directory is %s\n", gameData.directorySearchPath));
107 
108 	char dir[PATH_MAX];
109 	strcpy(dir, "");
110 
111 	sprintf(dir, "%s/.parallelrealities", userHome);
112 	if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
113 		exit(1);
114 
115 	sprintf(dir, "%s/.parallelrealities/virusKiller", userHome);
116 	if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
117 		exit(1);
118 
119 	char gameSavePath[PATH_MAX];
120 	sprintf(gameSavePath, "%s/.parallelrealities/virusKiller/", userHome);
121 	engine.setUserHome(gameSavePath);
122 }
123 #endif
124 
125 //
126 // see if we can load the private keyState
127 //
initMedalService()128 void initMedalService()
129 {
130 	SDL_FillRect(graphics.screen, NULL, graphics.black);
131 	graphics.drawString(400, 520, true, graphics.screen, "Contacting Medal Server - %s:%d", MEDAL_SERVER_HOST, MEDAL_SERVER_PORT);
132 	graphics.updateScreen();
133 
134 	char keyPath[PATH_MAX];
135 	char privateKey[20];
136 
137 	sprintf(keyPath, "%smedalKey", engine.userHomeDirectory);
138 
139 	debug(("Loading private key from %s\n", keyPath));
140 
141 	FILE *fp = fopen(keyPath, "rb");
142 
143 	if (!fp)
144 	{
145 		graphics.showMedalMessage(-1, "Medal Key not found - Online functions disabled");
146 		return;
147 	}
148 
149 	fscanf(fp, "%s", privateKey);
150 
151 	fclose(fp);
152 
153 	if (!medalServer.connect(privateKey))
154 	{
155 		graphics.drawString(400, 520, true, graphics.screen, "Server Connection Failed");
156 		graphics.updateScreen();
157 		SDL_Delay(2500);
158 	}
159 }
160 
loadConfig()161 bool loadConfig()
162 {
163 	char configPath[PATH_MAX];
164 
165 	sprintf(configPath, "%sconfig", engine.userHomeDirectory);
166 
167 	debug(("Loading Config from %s\n", configPath));
168 
169 	FILE *fp = fopen(configPath, "rb");
170 
171 	if (!fp)
172 		return true;
173 
174 	fread(&engine.fullScreen, sizeof(int), 1, fp);
175 	fread(&gameData.soundVolume, sizeof(int), 1, fp);
176 	fread(&gameData.musicVolume, sizeof(int), 1, fp);
177 	fread(&gameData.gamma, sizeof(int), 1, fp);
178 
179 	fread(&gameData.nightmareCount, sizeof(int), 1, fp);
180 
181 	for (int j = 0 ; j < 5 ; j++)
182 	{
183 		for (int i = 0 ; i < 10 ; i++)
184 		{
185 			fread(&gameData.highScore[j][i], sizeof(HighScore), 1, fp);
186 		}
187 	}
188 
189 	fclose(fp);
190 
191 	return false;
192 }
193 
saveConfig()194 void saveConfig()
195 {
196 	char configPath[PATH_MAX];
197 
198 	sprintf(configPath, "%sconfig", engine.userHomeDirectory);
199 
200 	FILE *fp = fopen(configPath, "wb");
201 
202 	if (!fp)
203 	{
204 		printf("Error Saving Config to %s\n", configPath);
205 		return;
206 	}
207 
208 	fwrite(&engine.fullScreen, sizeof(int), 1, fp);
209 	fwrite(&gameData.soundVolume, sizeof(int), 1, fp);
210 	fwrite(&gameData.musicVolume, sizeof(int), 1, fp);
211 	fwrite(&gameData.gamma, sizeof(int), 1, fp);
212 
213 	fwrite(&gameData.nightmareCount, sizeof(int), 1, fp);
214 
215 	for (int j = 0 ; j < 5 ; j++)
216 	{
217 		for (int i = 0 ; i < 10 ; i++)
218 		{
219 			fwrite(&gameData.highScore[j][i], sizeof(HighScore), 1, fp);
220 		}
221 	}
222 
223 	fclose(fp);
224 }
225 
226 /*
227 Chugg chugg chugg.... brrr... chugg chugg chugg...brrrrrr... chugg ch..
228 BRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMM!! Well, hopefully anyway! ;)
229 */
initSystem()230 void initSystem()
231 {
232 	#if UNIX
233 		setupUserHomeDirectory();
234 	#endif
235 
236 	bool displayLicense = loadConfig();
237 
238 	/* Initialize the SDL library */
239 	if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
240 		printf("Couldn't initialize SDL: %s\n", SDL_GetError());
241 		exit(1);
242 	}
243 
244 	if (!engine.fullScreen)
245 		graphics.screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, 0, SDL_HWPALETTE);
246 	else
247 		graphics.screen = SDL_SetVideoMode(SCREENWIDTH, SCREENHEIGHT, SCREENDEPTH, SDL_HWPALETTE | SDL_FULLSCREEN);
248 
249 	if (graphics.screen == NULL)
250 	{
251 		printf("Couldn't set %dx%dx%d video mode: %s\n", SCREENWIDTH, SCREENHEIGHT, SCREENDEPTH, SDL_GetError());
252 		exit(1);
253 	}
254 
255 	if (TTF_Init() < 0)
256 	{
257 		printf("Couldn't initialize SDL TTF: %s\n", SDL_GetError());
258 		exit(1);
259 	}
260 
261 	if (engine.useAudio)
262 	{
263 		if (Mix_OpenAudio(22050, AUDIO_S16, engine.useAudio, 1024) < 0)
264 		{
265 			printf("Warning: Couldn't set 22050 Hz 16-bit audio - Reason: %s\n", Mix_GetError());
266 			printf("Sound and Music will be disabled\n");
267 			engine.useAudio = 0;
268 		}
269 	}
270 
271 	SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
272 	SDL_ShowCursor(SDL_DISABLE);
273 
274 	graphics.registerEngine(&engine);
275 	graphics.mapColors();
276 
277 	audio.registerEngine(&engine);
278 	audio.setSoundVolume(gameData.soundVolume);
279 	audio.setMusicVolume(gameData.musicVolume);
280 
281 	srand(time(NULL));
282 
283 	#if USEPAK
284 
285 		char tempPath[PATH_MAX];
286 		sprintf(tempPath, "%sfont.ttf", engine.userHomeDirectory);
287 		remove(tempPath);
288 
289 		SDL_Delay(1000); // wait one second, just to be sure!
290 
291 		if (!engine.unpack("data/vera.ttf", PAK_FONT))
292 		{
293 			engine.reportFontFailure();
294 		}
295 	#endif
296 
297 	debug(("Trying to load correct font pixel sizes using a really half arsed routine!\n"));
298 	debug(("If it crashes then you'll know why!\n"));
299 
300 	graphics.loadFont(0, "data/vera.ttf", 7);
301 	graphics.loadFont(1, "data/vera.ttf", 9);
302 	graphics.loadFont(2, "data/vera.ttf", 11);
303 	graphics.loadFont(3, "data/vera.ttf", 13);
304 	graphics.loadFont(4, "data/vera.ttf", 15);
305 
306 	graphics.medal[0] = graphics.loadImage("gfx/main/medal_bronze_1.png");
307 	graphics.medal[1] = graphics.loadImage("gfx/main/award_star_silver_3.png");
308 	graphics.medal[2] = graphics.loadImage("gfx/main/shield.png");
309 	graphics.medal[3] = graphics.loadImage("gfx/main/ruby.png");
310 
311 	debug(("Font sizes all loaded!!\n"));
312 
313 	SDL_WM_SetIcon(graphics.loadImage("gfx/main/alienDevice.png"), NULL);
314 	SDL_WM_SetCaption("Virus Killer", "Virus Killer");
315 
316 	if (displayLicense)
317 		showLicense();
318 
319 	if (SDLNet_Init() < 0)
320 	{
321 		printf("SDLNet_Init: %s\n", SDLNet_GetError());
322 	}
323 	else
324 	{
325 		initMedalService();
326 	}
327 
328 	engine.allowQuit = true;
329 	engine.flushInput();
330 	engine.clearInput();
331 }
332 
333 /*
334 Removes [hopefully] all the resources that has been
335 loaded and created during the game. This is called by
336 atexit();
337 */
cleanup()338 void cleanup()
339 {
340 	char tempPath[PATH_MAX];
341 
342 	debug(("Cleaning Up...\n"));
343 
344 	debug(("Destroying GameData...\n"));
345 	gameData.destroy();
346 
347 	debug(("Freeing Audio...\n"));
348 	audio.destroy();
349 
350 	debug(("Closing Audio...\n"));
351 	if (engine.useAudio)
352 	{
353 		Mix_CloseAudio();
354 	}
355 
356 	debug(("Removing Music...\n"));
357 	sprintf(tempPath, "%smusic.mod", engine.userHomeDirectory);
358 	remove(tempPath);
359 
360 	debug(("Removing Font File...\n"));
361 	sprintf(tempPath, "%sfont.ttf", engine.userHomeDirectory);
362 	remove(tempPath);
363 
364 	debug(("Freeing Engine Data...\n"));
365 	engine.destroy();
366 
367 	debug(("Freeing Graphics...\n"));
368 	graphics.destroy();
369 
370 	debug(("Closing NET...\n"));
371 	SDLNet_Quit();
372 
373 	debug(("Closing SDL Sub System...\n"));
374 	SDL_Quit();
375 
376 	saveConfig();
377 
378 	debug(("All Done.\n"));
379 }
380