1 /*
2  * GNUjump
3  * =======
4  *
5  * Copyright (C) 2005-2008, Juan Pedro Bolivar Puente
6  *
7  * GNUjump is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GNUjump 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, see <http://www.gnu.org/licenses/>.
19  */
20 
21 #include "gnujump.h"
22 #include "setup.h"
23 #include "surface.h"
24 #include "sprite.h"
25 #include "tools.h"
26 
27 extern SDL_Surface *screen;
28 extern L_gblOptions gblOps;
29 
30 void
initGblOps(void)31 initGblOps (void)
32 {
33   int i;
34   char *homeDir;
35   char *cfgDir;
36 
37   gblOps.aa = 0;
38   gblOps.useGL = TRUE;
39   gblOps.w = 0;
40   gblOps.h = 0;
41   gblOps.bpp = BPPAUTO;
42 
43   gblOps.fps = FPS100;
44   gblOps.rotMode = ROTFULL;
45   gblOps.scrollMode = SOFTSCROLL;
46   gblOps.scrollBg = TRUE;
47   gblOps.trailMode = NORMALTRAIL;
48   gblOps.blur = 4;
49   gblOps.mpLives = 3;
50   gblOps.nplayers = 0;
51   gblOps.recReplay = 0;
52   gblOps.repFps = 40;
53   gblOps.sndvolume = 9;
54   gblOps.musvolume = 6;
55 
56 #ifndef WIN32
57   homeDir = getenv ("HOME");
58   cfgDir = malloc (sizeof (char) * (strlen (homeDir) + strlen (CONFDIR) + 2));
59   sprintf (cfgDir, "%s/" CONFDIR, homeDir);
60   if (access (cfgDir, F_OK) < 0)
61     mkdir (cfgDir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
62 #endif
63 
64   /* Setting up the Default skin as skin and English as the default lang. */
65 #ifdef WIN32
66   gblOps.dataDir =
67     malloc (sizeof (char) * (strlen ("skins/") + strlen (DEFTHEME) + 1));
68   sprintf (gblOps.dataDir, "skins/%s", DEFTHEME);
69   gblOps.repDir = malloc (sizeof (char) * (strlen (".") + 1));
70   sprintf (gblOps.repDir, ".");
71 #else
72   gblOps.repDir = malloc (sizeof (char) * (strlen (cfgDir) + 1));
73   sprintf (gblOps.repDir, "%s", cfgDir);
74 #ifndef DEVEL
75   gblOps.dataDir =
76     malloc (sizeof (char) *
77 	    (strlen (DATA_PREFIX) + strlen (PACKAGE) + strlen ("/skins/") +
78 	     strlen (DEFTHEME) + 2));
79   sprintf (gblOps.dataDir, "%s/%s/skins/%s", DATA_PREFIX, PACKAGE, DEFTHEME);
80 #else
81   gblOps.dataDir =
82     malloc (sizeof (char) * (strlen ("skins/") + strlen (DEFTHEME) + 1));
83   sprintf (gblOps.dataDir, "skins/%s", DEFTHEME);
84 #endif
85 #endif
86 
87   /* Setting up the list of skin and theme folders */
88 #ifdef WIN32
89   gblOps.ntfolders = 1;
90   gblOps.nrfolders = 1;
91   gblOps.themeDirs = malloc (sizeof (char *) * gblOps.ntfolders);
92   gblOps.repDirs = malloc (sizeof (char *) * gblOps.nrfolders);
93 
94   gblOps.themeDirs[0] = malloc (sizeof (char) * (strlen ("skins") + 1));
95   strcpy (gblOps.themeDirs[0], "skins");
96   gblOps.repDirs[0] = malloc (sizeof (char) * (strlen (".") + 1));
97   strcpy (gblOps.repDirs[0], ".");
98 #else
99   gblOps.ntfolders = 2;
100   gblOps.nrfolders = 1;
101   gblOps.themeDirs = malloc (sizeof (char *) * gblOps.ntfolders);
102   gblOps.repDirs = malloc (sizeof (char *) * gblOps.nrfolders);
103 
104   gblOps.themeDirs[0] = malloc (sizeof (char) * strlen (cfgDir) + 1);
105   gblOps.repDirs[0] = malloc (sizeof (char) * strlen (cfgDir) + 1);
106   strcpy (gblOps.themeDirs[0], cfgDir);
107   strcpy (gblOps.repDirs[0], cfgDir);
108 
109   free (cfgDir);
110 #ifndef DEVEL
111   gblOps.themeDirs[1] =
112     malloc (sizeof (char) *
113 	    (strlen (DATA_PREFIX) + strlen (PACKAGE) + strlen ("/skins") +
114 	     2));
115   sprintf (gblOps.themeDirs[1], "%s/%s/skins", DATA_PREFIX, PACKAGE);
116 #else
117   gblOps.themeDirs[1] = malloc (sizeof (char) * (strlen ("skins") + 2));
118   sprintf (gblOps.themeDirs[1], "skins");
119 #endif
120 #endif
121 
122   /* Default Keys */
123   gblOps.keys[0][LEFTK] = KEY_LEFT1;
124   gblOps.keys[1][LEFTK] = KEY_LEFT2;
125   gblOps.keys[2][LEFTK] = KEY_LEFT3;
126   gblOps.keys[3][LEFTK] = KEY_LEFT4;
127 
128   gblOps.keys[0][RIGHTK] = KEY_RIGHT1;
129   gblOps.keys[1][RIGHTK] = KEY_RIGHT2;
130   gblOps.keys[2][RIGHTK] = KEY_RIGHT3;
131   gblOps.keys[3][RIGHTK] = KEY_RIGHT4;
132 
133   gblOps.keys[0][JUMPK] = KEY_UP1;
134   gblOps.keys[1][JUMPK] = KEY_UP2;
135   gblOps.keys[2][JUMPK] = KEY_UP3;
136   gblOps.keys[3][JUMPK] = KEY_UP4;
137 
138   /* Default player names */
139   for (i = 0; i < MAX_PLAYERS; i++)
140     {
141       gblOps.pname[i] = malloc (sizeof (char) * (strlen (PNAME) + 4));
142       sprintf (gblOps.pname[i], "%s%d", PNAME, i + 1);
143     }
144 }
145 
146 void
cleanGblOps(void)147 cleanGblOps (void)
148 {
149   int i;
150 
151   free (gblOps.dataDir);
152   for (i = 0; i < MAX_PLAYERS; i++)
153     {
154       free (gblOps.pname[i]);
155     }
156   for (i = 0; i < gblOps.ntfolders; i++)
157     {
158       free (gblOps.themeDirs[i]);
159     }
160   for (i = 0; i < gblOps.nrfolders; i++)
161     {
162       free (gblOps.repDirs[i]);
163     }
164   free (gblOps.themeDirs);
165   free (gblOps.repDirs);
166 }
167 
168 int
loadConfigFile(char * fname)169 loadConfigFile (char *fname)
170 {
171   FILE *tfile;
172   int i;
173   char str[MAX_CHAR];
174 
175   if ((tfile = fopen (fname, "r")) == NULL)
176     {
177       fprintf (stderr,
178 	       _
179 	       ("WARNING: Can't open config file (%s). I will create one later.\n"),
180 	       fname);
181       return FALSE;
182     }
183   getValue_str (tfile, "protocol_version", str, FALSE);
184   if (strcmp (str, PROT_VERS) != 0)
185     {
186       fclose (tfile);
187       fprintf (stderr,
188 	       _
189 	       ("WARNING: Config file (%s) is not compatible with this version of gnujump. I will rewrite it later.\n"),
190 	       fname);
191       return FALSE;
192     }
193 
194   gblOps.fps = getValue_int (tfile, "fps_limit");
195   gblOps.rotMode = getValue_int (tfile, "rotation_mode");
196   gblOps.scrollMode = getValue_int (tfile, "scroll_mode");
197   gblOps.scrollBg = getValue_int (tfile, "scroll_bg");
198   gblOps.trailMode = getValue_int (tfile, "trail");
199   gblOps.blur = getValue_int (tfile, "blur");
200   gblOps.mpLives = getValue_int (tfile, "multiplayer_lives");
201   gblOps.nplayers = getValue_int (tfile, "number_players");
202   gblOps.recReplay = getValue_int (tfile, "record_replay");
203   gblOps.repFps = getValue_int (tfile, "replay_fps");
204 
205   gblOps.useGL = getValue_int (tfile, "use_opengl");
206   gblOps.bpp = getValue_int (tfile, "bpp");
207   gblOps.w = getValue_int (tfile, "screen_width");
208   gblOps.h = getValue_int (tfile, "screen_height");
209   gblOps.fullsc = getValue_int (tfile, "fullscreen");
210   gblOps.aa = getValue_int (tfile, "antialiasing");
211 
212   gblOps.sndvolume = getValue_int (tfile, "sound_volume");
213   gblOps.musvolume = getValue_int (tfile, "music_volume");
214 
215   gblOps.dataDir = getValue_charp (tfile, "default_skin");
216   gblOps.ntfolders = getValue_int (tfile, "skin_folders");
217   gblOps.themeDirs = malloc (sizeof (char *) * gblOps.ntfolders);
218   for (i = 0; i < gblOps.ntfolders; i++)
219     {
220       gblOps.themeDirs[i] = getValue_charp (tfile, "skin_dir");
221     }
222 
223   gblOps.repDir = getValue_charp (tfile, "replay_save_folder");
224   gblOps.nrfolders = getValue_int (tfile, "replay_folders");
225   gblOps.repDirs = malloc (sizeof (char *) * gblOps.nrfolders);
226   for (i = 0; i < gblOps.nrfolders; i++)
227     {
228       gblOps.repDirs[i] = getValue_charp (tfile, "replay_dir");
229     }
230 
231   for (i = 0; i < MAX_PLAYERS; i++)
232     {
233       getValue_str (tfile, "player_name", str, FALSE);
234       gblOps.pname[i] = malloc (sizeof (char) * (strlen (str) + 1));
235       strcpy (gblOps.pname[i], str);
236 
237       gblOps.keys[i][LEFTK] = getValue_int (tfile, "key_left");
238       gblOps.keys[i][RIGHTK] = getValue_int (tfile, "key_right");
239       gblOps.keys[i][JUMPK] = getValue_int (tfile, "key_jump");
240     }
241 
242   fclose (tfile);
243 
244   return TRUE;
245 }
246 
247 int
writeConfigFile(char * fname)248 writeConfigFile (char *fname)
249 {
250   FILE *tfile;
251   int i;
252 
253   if ((tfile = fopen (fname, "w")) == NULL)
254     {
255       fprintf (stderr,
256 	       _
257 	       ("WARNING: Can't open config file (%s). Make sure that it is not being used by another app.\n"),
258 	       fname);
259       return FALSE;
260     }
261 
262   putComment (tfile, "This file has been automatically generated by GNUjump");
263   putLine (tfile);
264   putValue_str (tfile, "protocol_version", PROT_VERS);
265 
266   putLine (tfile);
267   putComment (tfile, "Game options");
268   putValue_int (tfile, "fps_limit", gblOps.fps);
269   putValue_int (tfile, "rotation_mode", gblOps.rotMode);
270   putValue_int (tfile, "scroll_mode", gblOps.scrollMode);
271   putValue_int (tfile, "scroll_bg", gblOps.scrollBg);
272   putValue_int (tfile, "trail", gblOps.trailMode);
273   putValue_int (tfile, "blur", gblOps.blur);
274   putValue_int (tfile, "multiplayer_lives", gblOps.mpLives);
275   putValue_int (tfile, "number_players", gblOps.nplayers);
276   putValue_int (tfile, "record_replay", gblOps.recReplay);
277   putValue_int (tfile, "replay_fps", gblOps.repFps);
278 
279   putLine (tfile);
280   putComment (tfile, "Graphics options");
281   putValue_int (tfile, "use_opengl", gblOps.useGL);
282   putValue_int (tfile, "bpp", gblOps.bpp);
283   putValue_int (tfile, "screen_width", gblOps.w);
284   putValue_int (tfile, "screen_height", gblOps.h);
285   putValue_int (tfile, "fullscreen", gblOps.fullsc);
286   putValue_int (tfile, "antialiasing", gblOps.aa);
287 
288   putValue_int (tfile, "sound_volume", gblOps.sndvolume);
289   putValue_int (tfile, "music_volume", gblOps.musvolume);
290 
291   putLine (tfile);
292   putComment (tfile, "Skin options");
293   putValue_str (tfile, "default_skin", gblOps.dataDir);
294   putValue_int (tfile, "skin_folders", gblOps.ntfolders);
295   for (i = 0; i < gblOps.ntfolders; i++)
296     {
297       putValue_str (tfile, "skin_dir", gblOps.themeDirs[i]);
298     }
299 
300   putLine (tfile);
301   putComment (tfile, "Replay dir options");
302   putValue_str (tfile, "replay_save_folder", gblOps.repDir);
303   putValue_int (tfile, "replay_folders", gblOps.nrfolders);
304   for (i = 0; i < gblOps.nrfolders; i++)
305     {
306       putValue_str (tfile, "replay_dir", gblOps.repDirs[i]);
307     }
308 
309   putLine (tfile);
310   putComment (tfile, "Player options");
311   for (i = 0; i < MAX_PLAYERS; i++)
312     {
313       putValue_str (tfile, "player_name", gblOps.pname[i]);
314       putValue_int (tfile, "key_left", gblOps.keys[i][LEFTK]);
315       putValue_int (tfile, "key_right", gblOps.keys[i][RIGHTK]);
316       putValue_int (tfile, "key_jump", gblOps.keys[i][JUMPK]);
317       putLine (tfile);
318     }
319 
320   fclose (tfile);
321 
322   return TRUE;
323 }
324 
325 char *
getThemeComment(char * fname)326 getThemeComment (char *fname)
327 {
328   FILE *fh;
329   char str[MAX_CHAR];
330   char *ret = NULL;
331   char *file = NULL;
332 
333   file = malloc (sizeof (char) * (strlen (fname) + strlen (THEMEFILE) + 1));
334   strcpy (file, fname);
335   strcat (file, THEMEFILE);
336 
337   if ((fh = fopen (file, "r")) == NULL)
338     {
339       fprintf (stderr, _("WARNING: Can open theme file (%s).\n"), file);
340       free (file);
341       return NULL;
342     }
343 
344   getValue_str (fh, "format", str, FALSE);
345   if (strcmp (str, THEME_VERS) != 0)
346     {
347       fclose (fh);
348       fprintf (stderr,
349 	       _("WARNING: Theme file (%s) is not of the correct format.\n"),
350 	       file);
351       free (file);
352       return NULL;
353     }
354 
355   ret = getValue_charp (fh, "comment");
356   fclose (fh);
357 
358   printf (_("Successfully loaded comment from: %s\n"), file);
359   free (file);
360 
361   return ret;
362 }
363 
364 char *
getLangComment(char * fname)365 getLangComment (char *fname)
366 {
367   FILE *fh;
368   char str[MAX_CHAR];
369   char *ret = NULL;
370 
371   if ((fh = fopen (fname, "r")) == NULL)
372     {
373       fprintf (stderr, _("WARNING: Can open lang file (%s).\n"), fname);
374       return NULL;
375     }
376 
377   getValue_str (fh, "format", str, FALSE);
378   if (strcmp (str, LANG_VERS) != 0)
379     {
380       fclose (fh);
381       fprintf (stderr,
382 	       _("WARNING: Theme file (%s) is not of the correct format.\n"),
383 	       fname);
384       return NULL;
385     }
386 
387   ret = getValue_charp (fh, "comment");
388   fclose (fh);
389   printf (_("Successfully loaded comment from: %s\n"), fname);
390 
391   return ret;
392 }
393 
394 void
EngineInit()395 EngineInit ()
396 {
397   //Everything starts!!
398   if (SDL_Init (SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
399     {
400       fprintf (stderr, _("ERROR: SDL_Init did not work because: %s\n"),
401 	       SDL_GetError ());
402       exit (2);
403     }
404 
405   atexit (SDL_Quit);		//this avoids exiting without ending
406 
407   if (Mix_OpenAudio (MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
408     fprintf (stderr, _("ERROR: Mix_OpenAudio: %s\n"), Mix_GetError ());
409   else
410     resetVolumes ();
411 }
412 
413 void
setWindow()414 setWindow ()
415 {
416   int bpp;
417   const SDL_VideoInfo *info = NULL;
418 
419   switch (gblOps.bpp)
420     {
421     case BPPAUTO:
422       info = SDL_GetVideoInfo ();
423       bpp = info->vfmt->BitsPerPixel;
424       break;
425     case BPP32:
426       bpp = 32;
427       break;
428     case BPP16:
429       bpp = 16;
430       break;
431     case BPP8:
432       bpp = 8;
433       break;
434     default:
435       info = SDL_GetVideoInfo ();
436       bpp = info->vfmt->BitsPerPixel;
437       break;
438     }
439 
440   if (!gblOps.aa)
441     gblOps.texFilter = GL_NEAREST;
442   else
443     gblOps.texFilter = GL_LINEAR;
444 
445   if (gblOps.useGL)
446     {
447       if (SetVideoGl (gblOps.w, gblOps.h, gblOps.fullsc, bpp))
448 	SDL_WM_SetCaption ("GNUjump " VERSION " (OpenGL rendering)", NULL);
449       else
450 	gblOps.useGL = FALSE;
451     }
452   if (!gblOps.useGL)
453     {
454       SetVideoSw (gblOps.w, gblOps.h, gblOps.fullsc, bpp);
455       SDL_WM_SetCaption ("GNUjump " VERSION " (Sofware rendering)", NULL);
456     }
457 
458   printf (_("Window created. BPP: %d, Resolution: %dx%d, OpenGL: %d\n"),
459 	  screen->format->BitsPerPixel,
460 	  screen->w, screen->h, (screen->flags & SDL_OPENGL) == SDL_OPENGL);
461 
462   SDL_ShowCursor (SDL_DISABLE);
463 }
464 
465 int
SetVideoGl(int w,int h,int use_fullscreen,int bpp)466 SetVideoGl (int w, int h, int use_fullscreen, int bpp)
467 {
468   char *glstr;
469   int error = FALSE;
470 
471   SDL_GL_SetAttribute (SDL_GL_RED_SIZE, 5);
472   SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, 5);
473   SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE, 5);
474   SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 16);
475   SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
476 
477   if (use_fullscreen)
478     {
479       printf (_("Setting up an OpenGL fullscreen window.\n"));
480       screen = SDL_SetVideoMode (w, h, bpp, SDL_FULLSCREEN | SDL_OPENGL);
481       if (screen == NULL)
482 	{
483 	  fprintf (stderr,
484 		   _("ERROR: The screen wasn't initialized beacause: %s\n"),
485 		   SDL_GetError ());
486 	  use_fullscreen = 0;
487 	}
488     }
489   if (!use_fullscreen)
490     {
491       printf (_("Setting up an OpenGL window.\n"));
492       screen = SDL_SetVideoMode (w, h, bpp, SDL_OPENGL);
493 
494       if (screen == NULL)
495 	{
496 	  fprintf (stderr,
497 		   _("ERROR: The screen wasn't initialized beacause: %s\n"),
498 		   SDL_GetError ());
499 	  error = TRUE;
500 	}
501     }
502 
503   glstr = (char *) glGetString (GL_RENDERER);
504   if (!strcmp (glstr, "Mesa X11") || !strcmp (glstr, "Mesa GLX Indirect"))
505     {
506       error = TRUE;
507       printf
508 	("WARNING: OpenGl Renderer is %s. Falling back to software mode.",
509 	 glstr);
510     }
511 
512   /* If error */
513   if (error)
514     return FALSE;
515 
516   /*
517    * Set up OpenGL for 2D rendering.
518    */
519 
520   glDisable (GL_DEPTH_TEST);
521   glDisable (GL_CULL_FACE);
522 
523   glViewport (0, 0, screen->w, screen->h);
524   glMatrixMode (GL_PROJECTION);
525   glLoadIdentity ();
526   glOrtho (0.0f, screen->w, screen->h, 0.0f, -1.0f, 1.0f);
527   glMatrixMode (GL_MODELVIEW);
528   glLoadIdentity ();
529 
530   glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
531   glClear (GL_COLOR_BUFFER_BIT);
532 
533   return TRUE;
534 }
535 
536 void
SetVideoSw(int w,int h,int fullscreen,int bpp)537 SetVideoSw (int w, int h, int fullscreen, int bpp)
538 {
539   if (fullscreen)
540     {
541       printf (_("Setting up a software fullscreen window.\n"));
542       screen = SDL_SetVideoMode (w, h, bpp, SDL_FULLSCREEN);
543       if (screen == NULL)
544 	{
545 	  printf (_("ERROR: The screen wasn't initialized beacause: %s\n"),
546 		  SDL_GetError ());
547 	}
548     }
549   if (!fullscreen)
550     {				//Fullscreen OFF
551       printf (_("Setting up a software window.\n"));
552       screen =
553 	SDL_SetVideoMode (w, h, bpp, 0 /*SDL_HWSURFACE | SDL_DOUBLEBUF */ );
554       if (screen == NULL)
555 	{
556 	  printf (_("ERROR: The screen wasn't initialized beacause: %s\n"),
557 		  SDL_GetError ());
558 	}
559     }
560 }
561 
562 void
resetVolumes()563 resetVolumes ()
564 {
565   Mix_Volume (-1, ((float) gblOps.sndvolume / 9.0) * MIX_MAX_VOLUME);
566   Mix_VolumeMusic (((float) gblOps.musvolume / 9.0) * MIX_MAX_VOLUME);
567 }
568 
569 int
loadSounds(data_t * data,char * fname)570 loadSounds (data_t * data, char *fname)
571 {
572   FILE *fh;
573   char str[MAX_CHAR];
574   char *file = NULL;
575 
576   file = malloc (sizeof (char) * (strlen (fname) + strlen (SOUNDFILE) + 1));
577   strcpy (file, fname);
578   strcat (file, SOUNDFILE);
579 
580   printf (_("Loading sounds: %s\n"), file);
581   data->soundloaded = TRUE;
582 
583   if ((fh = fopen (file, "r")) == NULL)
584     {
585       fprintf (stderr, _("ERROR: Can open sounds file (%s).\n"), file);
586       free (file);
587       return 0;
588     }
589 
590   getValue_str (fh, "format", str, FALSE);
591   if (strcmp (str, SOUND_VERS) != 0)
592     {
593       fclose (fh);
594       fprintf (stderr,
595 	       _("ERROR: Sound file (%s) is not of the correct format.\n"),
596 	       file);
597       free (file);
598       return 0;
599     }
600 
601   data->sndauth = getValue_charp (fh, "author");
602 
603   getValue_str (fh, "mus_game", str, fname);
604   data->musgame = Mix_LoadMUS (str);
605 
606   getValue_str (fh, "snd_die", str, fname);
607   data->gdie = Mix_LoadWAV (str);
608   getValue_str (fh, "snd_fall", str, fname);
609   data->gfall = Mix_LoadWAV (str);
610   getValue_str (fh, "snd_jump", str, fname);
611   data->gjump = Mix_LoadWAV (str);
612   getValue_str (fh, "snd_question", str, fname);
613   data->gquestion = Mix_LoadWAV (str);
614   getValue_str (fh, "snd_record", str, fname);
615   data->grecord = Mix_LoadWAV (str);
616 
617   getValue_str (fh, "mus_menu", str, fname);
618   data->musmenu = Mix_LoadMUS (str);
619   getValue_str (fh, "snd_click", str, fname);
620   data->mclick = Mix_LoadWAV (str);
621   getValue_str (fh, "snd_back", str, fname);
622   data->mback = Mix_LoadWAV (str);
623 
624   fclose (fh);
625 
626   free (file);
627 
628   return TRUE;
629 }
630 
631 void
freeSounds(data_t * data)632 freeSounds (data_t * data)
633 {
634   Mix_FreeChunk (data->gdie);
635   Mix_FreeChunk (data->gfall);
636   Mix_FreeChunk (data->gjump);
637   Mix_FreeChunk (data->gquestion);
638   Mix_FreeChunk (data->grecord);
639   Mix_FreeChunk (data->mclick);
640   Mix_FreeChunk (data->mback);
641   Mix_FreeMusic (data->musgame);
642   Mix_FreeMusic (data->musmenu);
643   free (data->sndauth);
644   data->soundloaded = 0;
645 }
646 
647 int
loadGraphics(data_t * data,char * fname)648 loadGraphics (data_t * data, char *fname)
649 {
650   FILE *fh;
651   char str[MAX_CHAR];
652   SDL_Surface *surf;
653   int i;
654   Uint8 b, g, r;
655   char *file = NULL;
656 
657   file = malloc (sizeof (char) * (strlen (fname) + strlen (THEMEFILE) + 1));
658   strcpy (file, fname);
659   strcat (file, THEMEFILE);
660 
661   printf (_("Loading theme: %s\n"), file);
662 
663   if ((fh = fopen (file, "r")) == NULL)
664     {
665       fprintf (stderr, _("ERROR: Can open theme file (%s).\n"), file);
666       free (file);
667       return 0;
668     }
669 
670   /*
671    * Global options
672    */
673   getValue_str (fh, "format", str, FALSE);
674   if (strcmp (str, THEME_VERS) != 0)
675     {
676       fclose (fh);
677       fprintf (stderr,
678 	       _("ERROR: Theme file (%s) is not of the correct format.\n"),
679 	       file);
680       free (file);
681       return 0;
682     }
683 
684   skipValueStr (fh);		/* Comment */
685   data->gfxauth = getValue_charp (fh, "author");
686 
687   gblOps.w = getValue_int (fh, "window_width");
688   gblOps.h = getValue_int (fh, "window_height");
689 
690   setWindow ();
691 
692   getValue_str (fh, "sound_theme", str, FALSE);
693   if (data->soundloaded)
694     freeSounds (data);
695   if (!strcmp (str, "default"))
696     loadSounds (data, DEFSOUND);
697   else
698     loadSounds (data, str);
699 
700   /*
701    * Mouse icon
702    */
703   getValue_str (fh, "mouse_idle", str, fname);
704   data->mouse[M_IDLE] = loadSpriteData (str, 1, fname);
705   getValue_str (fh, "mouse_over", str, fname);
706   data->mouse[M_OVER] = loadSpriteData (str, 1, fname);
707   getValue_str (fh, "mouse_down", str, fname);
708   data->mouse[M_DOWN] = loadSpriteData (str, 1, fname);
709 
710   data->mouseX = getValue_int (fh, "mouse_x");
711   data->mouseY = getValue_int (fh, "mouse_y");
712 
713   /*
714    * Menu data
715    */
716   getValue_str (fh, "menu_bg", str, fname);
717   data->menuBg = JPB_LoadImg (str, gblOps.useGL, 0, 0, 0);
718   getValue_str (fh, "menu_dwarrow", str, fname);
719   data->dwArrow = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
720   getValue_str (fh, "menu_uparrow", str, fname);
721   data->upArrow = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
722 
723   getValue_str (fh, "menu_font", str, fname);
724   surf = IMG_Load (str);
725   data->menufont = SFont_InitFont (str, surf, gblOps.useGL, 1);
726   SDL_FreeSurface (surf);
727 
728   getValue_str (fh, "tip_font", str, fname);
729   surf = IMG_Load (str);
730   data->tipfont = SFont_InitFont (str, surf, gblOps.useGL, 1);
731   SDL_FreeSurface (surf);
732 
733   data->mAlign = getValue_int (fh, "menu_align");
734   data->tAlign = getValue_int (fh, "tip_align");
735 
736   data->menuX = getValue_int (fh, "menu_x");
737   data->menuY = getValue_int (fh, "menu_y");
738   data->menuW = getValue_int (fh, "menu_width");
739   data->mMaxOps = getValue_int (fh, "menu_max_options");
740 
741   data->mDwArrowX = getValue_int (fh, "menu_dwarrow_x");
742   data->mDwArrowY = getValue_int (fh, "menu_dwarrow_y");
743   data->mUpArrowX = getValue_int (fh, "menu_uparrow_x");
744   data->mUpArrowY = getValue_int (fh, "menu_uparrow_y");
745 
746   data->mMargin = getValue_int (fh, "menu_margin");
747 
748   data->tipX = getValue_int (fh, "tip_x");
749   data->tipY = getValue_int (fh, "tip_y");
750   data->tipW = getValue_int (fh, "tip_width");
751   data->tipH = getValue_int (fh, "tip_height");
752 
753   r = getValue_int (fh, "hl_red");
754   g = getValue_int (fh, "hl_green");
755   b = getValue_int (fh, "hl_blue");
756   data->hlalpha = getValue_int (fh, "hl_alpha");
757   data->hlcolor = SDL_MapRGB (screen->format, r, g, b);
758 
759   /*
760    * In-game data
761    */
762   getValue_str (fh, "game_bg", str, fname);
763   data->gameBg = JPB_LoadImg (str, gblOps.useGL, 0, 0, 0);
764 
765   getValue_str (fh, "live_pic", str, fname);
766   data->livePic = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
767   data->liveAlign = getValue_int (fh, "live_align");
768 
769   getValue_str (fh, "score_font", str, fname);
770   surf = IMG_Load (str);
771   data->scorefont = SFont_InitFont (str, surf, gblOps.useGL, 1);
772   SDL_FreeSurface (surf);
773 
774   getValue_str (fh, "timer_font", str, fname);
775   surf = IMG_Load (str);
776   data->timefont = SFont_InitFont (str, surf, gblOps.useGL, 1);
777   SDL_FreeSurface (surf);
778 
779   getValue_str (fh, "game_font", str, fname);
780   surf = IMG_Load (str);
781   data->textfont = SFont_InitFont (str, surf, gblOps.useGL, 1);
782   SDL_FreeSurface (surf);
783 
784   r = getValue_int (fh, "g_red");
785   g = getValue_int (fh, "g_green");
786   b = getValue_int (fh, "g_blue");
787   data->galpha = getValue_int (fh, "g_alpha");
788   data->gcolor = SDL_MapRGB (screen->format, r, g, b);
789 
790   data->gameX = getValue_int (fh, "game_x");
791   data->gameY = getValue_int (fh, "game_y");
792 
793   data->gameTileH = getValue_int (fh, "game_tile_h");
794   data->borderTileH = getValue_int (fh, "border_tile_h");
795   data->borderTileW = getValue_int (fh, "border_tile_w");
796 
797   data->timeX = getValue_int (fh, "timer_x");
798   data->timeY = getValue_int (fh, "timer_y");
799 
800   for (i = 0; i < MAX_PLAYERS; i++)
801     {
802       data->scoreX[i] = getValue_int (fh, "score_x");
803       data->scoreY[i] = getValue_int (fh, "score_y");
804       data->livesX[i] = getValue_int (fh, "lives_x");
805       data->livesY[i] = getValue_int (fh, "lives_y");
806     }
807 
808   getValue_str (fh, "floor_left", str, fname);
809   data->floorL = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
810   getValue_str (fh, "floor_right", str, fname);
811   data->floorR = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
812   getValue_str (fh, "floor_center", str, fname);
813   data->floorC = JPB_LoadImg (str, gblOps.useGL, 1, 0, 0);
814 
815   for (i = 0; i < MAX_PLAYERS; i++)
816     {
817       getValue_str (fh, "hero_stand_anim", str, fname);
818       data->heroSprite[i][H_STAND] = loadSpriteDataRot (str, 2, fname);
819       getValue_str (fh, "hero_run_anim", str, fname);
820       data->heroSprite[i][H_WALK] = loadSpriteDataRot (str, 2, fname);
821       getValue_str (fh, "hero_jump_anim", str, fname);
822       data->heroSprite[i][H_JUMP] = loadSpriteDataRot (str, 2, fname);
823     }
824 
825   for (i = 0; i < MAX_PLAYERS; i++)
826     {
827       data->tcolorr[i] = getValue_int (fh, "trail_red");
828       data->tcolorg[i] = getValue_int (fh, "trail_green");
829       data->tcolorb[i] = getValue_int (fh, "trail_blue");
830     }
831 
832   fclose (fh);
833 
834   free (file);
835 
836   return TRUE;
837 }
838 
839 void
freeGraphics(data_t * data)840 freeGraphics (data_t * data)
841 {
842   int i, j;
843   for (j = 0; j < M_STATES; j++)
844     freeSpriteData (data->mouse[j]);
845   JPB_FreeSurface (data->gameBg);
846   JPB_FreeSurface (data->livePic);
847   JPB_FreeSurface (data->floorR);
848   JPB_FreeSurface (data->floorL);
849   JPB_FreeSurface (data->floorC);
850   JPB_FreeSurface (data->menuBg);
851   JPB_FreeSurface (data->dwArrow);
852   JPB_FreeSurface (data->upArrow);
853   SFont_FreeFont (data->scorefont);
854   SFont_FreeFont (data->textfont);
855   SFont_FreeFont (data->menufont);
856   SFont_FreeFont (data->tipfont);
857   for (i = 0; i < MAX_PLAYERS; i++)
858     {
859       for (j = 0; j < HEROANIMS; j++)
860 	freeSpriteDataRot (data->heroSprite[i][j]);
861     }
862   free (data->gfxauth);
863 }
864