Space also hits menus.
[supertux.git] / src / setup.c
1 /*
2   setup.c
3   
4   Super Tux - Setup
5   
6   by Bill Kendrick
7   bill@newbreedsoftware.com
8   http://www.newbreedsoftware.com/supertux/
9   
10   April 11, 2000 - February 1st, 2004
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <SDL.h>
19 #include <SDL_image.h>
20 #ifndef NOOPENGL
21 #include <SDL_opengl.h>
22 #endif
23
24 #ifdef LINUX
25 #include <pwd.h>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <dirent.h>
29 #include <ctype.h>
30 #endif
31
32 #include "defines.h"
33 #include "globals.h"
34 #include "setup.h"
35 #include "screen.h"
36 #include "texture.h"
37 #include "menu.h"
38 #include "gameloop.h"
39
40 /* Local function prototypes: */
41
42 void seticon(void);
43 void usage(char * prog, int ret);
44
45 /* Does the given file exist and is it accessible? */
46 int faccessible(char *filename)
47 {
48   struct stat filestat;
49   if (stat(filename, &filestat) == -1)
50     return NO;
51   else
52     return YES;
53 }
54
55 /* Can we write to this location? */
56 int fwriteable(char *filename)
57 {
58   FILE* fi;
59   fi = fopen(filename, "wa");
60   if (fi == NULL)
61     {
62       return NO;
63     }
64   return YES;
65 }
66
67 /* Makes sure a directory is created in either the SuperTux base directory or the SuperTux base directory.*/
68 int fcreatedir(char* relative_dir)
69 {
70   char path[1024];
71   snprintf(path, 1024, "%s/%s/", st_dir, relative_dir);
72   if(mkdir(path,0755) != 0)
73     {
74       snprintf(path, 1024, "%s/%s/", DATA_PREFIX, relative_dir);
75       if(mkdir(path,0755) != 0)
76         {
77           return NO;
78         }
79       else
80         {
81           return YES;
82         }
83     }
84   else
85     {
86       return YES;
87     }
88 }
89
90 /* Get all names of sub-directories in a certain directory. */
91 /* Returns the number of sub-directories found. */
92 /* Note: The user has to free the allocated space. */
93 string_list_type dsubdirs(char *rel_path, char* expected_file)
94 {
95   DIR *dirStructP;
96   struct dirent *direntp;
97   int i = 0;
98   string_list_type sdirs;
99   char filename[1024];
100   char path[1024];
101
102   string_list_init(&sdirs);
103   sprintf(path,"%s/%s",st_dir,rel_path);
104   if((dirStructP = opendir(path)) != NULL)
105     {
106       while((direntp = readdir(dirStructP)) != NULL)
107         {
108           char absolute_filename[1024];
109           struct stat buf;
110
111           sprintf(absolute_filename, "%s/%s", path, direntp->d_name);
112
113           if (stat(absolute_filename, &buf) == 0 && S_ISDIR(buf.st_mode))
114             {
115               if(expected_file != NULL)
116                 {
117                   sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file);
118                   if(!faccessible(filename))
119                     continue;
120                 }
121
122                 string_list_add_item(&sdirs,direntp->d_name);
123             }
124         }
125       closedir(dirStructP);
126     }
127
128   sprintf(path,"%s/%s",DATA_PREFIX,rel_path);
129   if((dirStructP = opendir(path)) != NULL)
130     {
131       while((direntp = readdir(dirStructP)) != NULL)
132         {
133           char absolute_filename[1024];
134           struct stat buf;
135
136           sprintf(absolute_filename, "%s/%s", path, direntp->d_name);
137
138           if (stat(absolute_filename, &buf) == 0 && S_ISDIR(buf.st_mode))
139             {
140               if(expected_file != NULL)
141                 {
142                   sprintf(filename,"%s/%s/%s",path,direntp->d_name,expected_file);
143                   if(!faccessible(filename))
144                     {
145                       continue;
146                     }
147                   else
148                     {
149                       sprintf(filename,"%s/%s/%s/%s",st_dir,rel_path,direntp->d_name,expected_file);
150                       if(faccessible(filename))
151                         continue;
152                     }
153                 }
154
155                 string_list_add_item(&sdirs,direntp->d_name);
156             }
157         }
158       closedir(dirStructP);
159     }
160
161   return sdirs;
162 }
163
164 string_list_type dfiles(char *rel_path, char* exception_str)
165 {
166   DIR *dirStructP;
167   struct dirent *direntp;
168   int i = 0;
169   string_list_type sdirs;
170   char filename[1024];
171   char path[1024];
172
173   string_list_init(&sdirs);
174   sprintf(path,"%s/%s",st_dir,rel_path);
175   if((dirStructP = opendir(path)) != NULL)
176     {
177       while((direntp = readdir(dirStructP)) != NULL)
178         {
179           char absolute_filename[1024];
180           struct stat buf;
181
182           sprintf(absolute_filename, "%s/%s", path, direntp->d_name);
183
184           if (stat(absolute_filename, &buf) == 0 && S_ISREG(buf.st_mode))
185             {
186               if(exception_str != NULL)
187                 {
188                   if(strstr(direntp->d_name,exception_str) != NULL)
189                     continue;
190                 }
191
192                 string_list_add_item(&sdirs,direntp->d_name);
193             }
194         }
195       closedir(dirStructP);
196     }
197
198   sprintf(path,"%s/%s",DATA_PREFIX,rel_path);
199   if((dirStructP = opendir(path)) != NULL)
200     {
201       while((direntp = readdir(dirStructP)) != NULL)
202         {
203           char absolute_filename[1024];
204           struct stat buf;
205
206           sprintf(absolute_filename, "%s/%s", path, direntp->d_name);
207
208           if (stat(absolute_filename, &buf) == 0 && S_ISREG(buf.st_mode))
209             {
210               if(exception_str != NULL)
211                 {
212                   if(strstr(direntp->d_name,exception_str) != NULL)
213                     continue;
214                 }
215
216                 string_list_add_item(&sdirs,direntp->d_name);
217             }
218         }
219       closedir(dirStructP);
220     }
221
222   return sdirs;
223 }
224
225 void free_strings(char **strings, int num)
226 {
227   int i;
228   for(i=0; i < num; ++i)
229     free(strings[i]);
230 }
231
232 /* --- SETUP --- */
233 /* Set SuperTux configuration and save directories */
234 void st_directory_setup(void)
235 {
236   char *home;
237   char str[1024];
238   /* Get home directory (from $HOME variable)... if we can't determine it,
239      use the current directory ("."): */
240   if (getenv("HOME") != NULL)
241     home = getenv("HOME");
242   else
243     home = ".";
244
245   st_dir = (char *) malloc(sizeof(char) * (strlen(home) +
246                            strlen("/.supertux") + 1));
247   strcpy(st_dir, home);
248   strcat(st_dir, "/.supertux");
249
250   st_save_dir = (char *) malloc(sizeof(char) * (strlen(st_dir) + strlen("/save") + 1));
251
252   strcpy(st_save_dir,st_dir);
253   strcat(st_save_dir,"/save");
254
255   /* Create them. In the case they exist they won't destroy anything. */
256 #ifdef LINUX
257
258   mkdir(st_dir, 0755);
259   mkdir(st_save_dir, 0755);
260
261   sprintf(str, "%s/levels", st_dir);
262   mkdir(str, 0755);
263 #else
264   #ifdef WIN32
265
266   mkdir(st_dir);
267   mkdir(st_save_dir);
268   sprintf(str, "%s/levels", st_dir);
269   mkdir(str);
270 #endif
271 #endif
272
273 }
274
275 /* Create and setup menus. */
276 void st_menu(void)
277 {
278   menu_init(&main_menu);
279   menu_additem(&main_menu,menu_item_create(MN_LABEL,"Main Menu",0,0));
280   menu_additem(&main_menu,menu_item_create(MN_HL,"",0,0));
281   menu_additem(&main_menu,menu_item_create(MN_ACTION,"Start Game",0,0));
282   menu_additem(&main_menu,menu_item_create(MN_GOTO,"Load Game",0,&load_game_menu));
283   menu_additem(&main_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu));
284   menu_additem(&main_menu,menu_item_create(MN_ACTION,"Level editor",0,0));
285   menu_additem(&main_menu,menu_item_create(MN_HL,"",0,0));
286   menu_additem(&main_menu,menu_item_create(MN_ACTION,"Quit",0,0));
287
288   menu_init(&options_menu);
289   menu_additem(&options_menu,menu_item_create(MN_LABEL,"Options",0,0));
290   menu_additem(&options_menu,menu_item_create(MN_HL,"",0,0));
291   menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Fullscreen",use_fullscreen,0));
292   if(audio_device == YES)
293     {
294       menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Sound     ",use_sound,0));
295       menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Music     ",use_music,0));
296     }
297   else
298     {
299       menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Sound     ",use_sound,0));
300       menu_additem(&options_menu,menu_item_create(MN_DEACTIVE,"Music     ",use_music,0));
301     }
302   menu_additem(&options_menu,menu_item_create(MN_TOGGLE,"Show FPS  ",show_fps,0));
303   menu_additem(&options_menu,menu_item_create(MN_HL,"",0,0));
304   menu_additem(&options_menu,menu_item_create(MN_BACK,"Back",0,0));
305
306   menu_init(&load_game_menu);
307   menu_additem(&load_game_menu,menu_item_create(MN_LABEL,"Load Game",0,0));
308   menu_additem(&load_game_menu,menu_item_create(MN_HL,"",0,0));
309   menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 1",0,0));
310   menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 2",0,0));
311   menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 3",0,0));
312   menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 4",0,0));
313   menu_additem(&load_game_menu,menu_item_create(MN_DEACTIVE,"Slot 5",0,0));
314   menu_additem(&load_game_menu,menu_item_create(MN_HL,"",0,0));
315   menu_additem(&load_game_menu,menu_item_create(MN_BACK,"Back",0,0));
316
317   menu_init(&save_game_menu);
318   menu_additem(&save_game_menu,menu_item_create(MN_LABEL,"Save Game",0,0));
319   menu_additem(&save_game_menu,menu_item_create(MN_HL,"",0,0));
320   menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 1",0,0));
321   menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 2",0,0));
322   menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 3",0,0));
323   menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 4",0,0));
324   menu_additem(&save_game_menu,menu_item_create(MN_DEACTIVE,"Slot 5",0,0));
325   menu_additem(&save_game_menu,menu_item_create(MN_HL,"",0,0));
326   menu_additem(&save_game_menu,menu_item_create(MN_BACK,"Back",0,0));
327
328   menu_init(&game_menu);
329   menu_additem(&game_menu,menu_item_create(MN_LABEL,"InGame Menu",0,0));
330   menu_additem(&game_menu,menu_item_create(MN_HL,"",0,0));
331   menu_additem(&game_menu,menu_item_create(MN_ACTION,"Return To Game",0,0));
332   menu_additem(&game_menu,menu_item_create(MN_GOTO,"Save Game",0,&save_game_menu));
333   menu_additem(&game_menu,menu_item_create(MN_GOTO,"Load Game",0,&load_game_menu));
334   menu_additem(&game_menu,menu_item_create(MN_GOTO,"Options",0,&options_menu));
335   menu_additem(&game_menu,menu_item_create(MN_HL,"",0,0));
336   menu_additem(&game_menu,menu_item_create(MN_ACTION,"Quit Game",0,0));
337
338   menu_init(&highscore_menu);
339   menu_additem(&highscore_menu,menu_item_create(MN_TEXTFIELD,"Enter your name:",0,0));
340
341 }
342
343 void update_load_save_game_menu(menu_type* pmenu, int load)
344 {
345   int i;
346
347   for(i = 2; i < 7; ++i)
348     {
349       char *tmp;
350       slotinfo(&tmp,i-1);
351       if(load && strlen(tmp) == strlen("Slot X - Free") )
352         pmenu->item[i].kind = MN_DEACTIVE;
353       else
354         pmenu->item[i].kind = MN_ACTION;
355       menu_item_change_text(&pmenu->item[i],tmp);
356       free(tmp);
357     }
358 }
359
360 void process_save_load_game_menu(int save)
361 {
362   int slot;
363   switch (slot = menu_check(save ? &save_game_menu : &load_game_menu))
364     {
365     default:
366       if(slot != -1)
367         {
368           if(save == YES)
369             {
370               savegame(slot);
371             }
372           else
373             {
374               if(game_started == NO)
375                 gameloop("whatever",slot,ST_GL_LOAD_GAME);
376               else
377                 loadgame(slot);
378             }
379           st_pause_ticks_stop();
380         }
381       break;
382     }
383 }
384
385 /* Handle changes made to global settings in the options menu. */
386 void process_options_menu(void)
387 {
388   switch (menu_check(&options_menu))
389     {
390     case 2:
391       if(use_fullscreen != options_menu.item[2].toggled)
392         {
393           use_fullscreen = !use_fullscreen;
394           st_video_setup();
395         }
396       break;
397     case 3:
398       if(use_sound != options_menu.item[3].toggled)
399         use_sound = !use_sound;
400       break;
401     case 4:
402       if(use_music != options_menu.item[4].toggled)
403         {
404           if(use_music == YES)
405             {
406               if(playing_music())
407                 {
408                   halt_music();
409                 }
410               use_music = NO;
411             }
412           else
413             {
414               use_music = YES;
415               if (!playing_music())
416                 {
417                   play_current_music();
418                 }
419             }
420         }
421       break;
422     case 5:
423       if(show_fps != options_menu.item[5].toggled)
424         show_fps = !show_fps;
425       break;
426     }
427 }
428
429 void st_general_setup(void)
430 {
431   /* Seed random number generator: */
432
433   srand(SDL_GetTicks());
434
435   /* Load global images: */
436
437   text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png", TEXT_TEXT, 16,18);
438   text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png", TEXT_TEXT, 16,18);
439   text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png", TEXT_TEXT, 16,18);
440   text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png", TEXT_TEXT, 16,18);
441   text_load(&white_text,DATA_PREFIX "/images/status/letters-white.png", TEXT_TEXT, 16,18);
442   text_load(&white_small_text,DATA_PREFIX "/images/status/letters-white-small.png", TEXT_TEXT, 8,9);
443   text_load(&white_big_text,DATA_PREFIX "/images/status/letters-white-big.png", TEXT_TEXT, 24,27);
444   text_load(&yellow_nums,DATA_PREFIX "/images/status/numbers.png", TEXT_NUM, 32,32);
445
446   /* Load GUI/menu images: */
447   texture_load(&checkbox, DATA_PREFIX "/images/status/checkbox.png", USE_ALPHA);
448   texture_load(&checkbox_checked, DATA_PREFIX "/images/status/checkbox-checked.png", USE_ALPHA);
449   texture_load(&back, DATA_PREFIX "/images/status/back.png", USE_ALPHA);
450   texture_load(&arrow_left, DATA_PREFIX "/images/icons/left.png", USE_ALPHA);
451   texture_load(&arrow_right, DATA_PREFIX "/images/icons/right.png", USE_ALPHA);
452
453   /* Set icon image: */
454
455   seticon();
456   SDL_EnableUNICODE(1);
457
458 }
459
460 void st_general_free(void)
461 {
462
463   /* Free global images: */
464
465   text_free(&black_text);
466   text_free(&gold_text);
467   text_free(&white_text);
468   text_free(&blue_text);
469   text_free(&red_text);
470   text_free(&white_small_text);
471
472   /* Free GUI/menu images: */
473   texture_free(&checkbox);
474   texture_free(&checkbox_checked);
475   texture_free(&back);
476
477   /* Free menus */
478
479   menu_free(&main_menu);
480   menu_free(&game_menu);
481   menu_free(&options_menu);
482   menu_free(&highscore_menu);
483
484 }
485
486 void st_video_setup(void)
487 {
488
489   if(screen != NULL)
490     SDL_FreeSurface(screen);
491
492   /* Init SDL Video: */
493
494   if (SDL_Init(SDL_INIT_VIDEO) < 0)
495     {
496       fprintf(stderr,
497               "\nError: I could not initialize video!\n"
498               "The Simple DirectMedia error that occured was:\n"
499               "%s\n\n", SDL_GetError());
500       exit(1);
501     }
502
503   /* Open display: */
504
505   if(use_gl)
506     st_video_setup_gl();
507   else
508     st_video_setup_sdl();
509
510   texture_setup();
511
512   /* Set window manager stuff: */
513
514   SDL_WM_SetCaption("Super Tux", "Super Tux");
515
516 }
517
518 void st_video_setup_sdl(void)
519 {
520   SDL_FreeSurface(screen);
521
522   if (use_fullscreen == YES)
523     {
524       screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */
525       if (screen == NULL)
526         {
527           fprintf(stderr,
528                   "\nWarning: I could not set up fullscreen video for "
529                   "640x480 mode.\n"
530                   "The Simple DirectMedia error that occured was:\n"
531                   "%s\n\n", SDL_GetError());
532           use_fullscreen = NO;
533         }
534     }
535   else
536     {
537       screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF );
538
539       if (screen == NULL)
540         {
541           fprintf(stderr,
542                   "\nError: I could not set up video for 640x480 mode.\n"
543                   "The Simple DirectMedia error that occured was:\n"
544                   "%s\n\n", SDL_GetError());
545           exit(1);
546         }
547     }
548 }
549
550 void st_video_setup_gl(void)
551 {
552 #ifndef NOOPENGL
553
554   SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
555   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
556   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
557   SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
558   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
559
560   if (use_fullscreen == YES)
561     {
562       screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL) ; /* | SDL_HWSURFACE); */
563       if (screen == NULL)
564         {
565           fprintf(stderr,
566                   "\nWarning: I could not set up fullscreen video for "
567                   "640x480 mode.\n"
568                   "The Simple DirectMedia error that occured was:\n"
569                   "%s\n\n", SDL_GetError());
570           use_fullscreen = NO;
571         }
572     }
573   else
574     {
575       screen = SDL_SetVideoMode(640, 480, 32, SDL_OPENGL);
576
577       if (screen == NULL)
578         {
579           fprintf(stderr,
580                   "\nError: I could not set up video for 640x480 mode.\n"
581                   "The Simple DirectMedia error that occured was:\n"
582                   "%s\n\n", SDL_GetError());
583           exit(1);
584         }
585     }
586
587   /*
588    * Set up OpenGL for 2D rendering.
589    */
590   glDisable(GL_DEPTH_TEST);
591   glDisable(GL_CULL_FACE);
592
593   glViewport(0, 0, screen->w, screen->h);
594   glMatrixMode(GL_PROJECTION);
595   glLoadIdentity();
596   glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
597
598   glMatrixMode(GL_MODELVIEW);
599   glLoadIdentity();
600   glTranslatef(0.0f, 0.0f, 0.0f);
601
602 #endif
603
604 }
605
606 void st_joystick_setup(void)
607 {
608
609   /* Init Joystick: */
610
611 #ifdef JOY_YES
612   use_joystick = YES;
613
614   if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
615     {
616       fprintf(stderr, "Warning: I could not initialize joystick!\n"
617               "The Simple DirectMedia error that occured was:\n"
618               "%s\n\n", SDL_GetError());
619
620       use_joystick = NO;
621     }
622   else
623     {
624       /* Open joystick: */
625
626       if (SDL_NumJoysticks() <= 0)
627         {
628           fprintf(stderr, "Warning: No joysticks are available.\n");
629
630           use_joystick = NO;
631         }
632       else
633         {
634           js = SDL_JoystickOpen(0);
635
636           if (js == NULL)
637             {
638               fprintf(stderr, "Warning: Could not open joystick 1.\n"
639                       "The Simple DirectMedia error that occured was:\n"
640                       "%s\n\n", SDL_GetError());
641
642               use_joystick = NO;
643             }
644           else
645             {
646               /* Check for proper joystick configuration: */
647
648               if (SDL_JoystickNumAxes(js) < 2)
649                 {
650                   fprintf(stderr,
651                           "Warning: Joystick does not have enough axes!\n");
652
653                   use_joystick = NO;
654                 }
655               else
656                 {
657                   if (SDL_JoystickNumButtons(js) < 2)
658                     {
659                       fprintf(stderr,
660                               "Warning: "
661                               "Joystick does not have enough buttons!\n");
662
663                       use_joystick = NO;
664                     }
665                 }
666             }
667         }
668     }
669 #endif
670
671 }
672
673 void st_audio_setup(void)
674 {
675
676   /* Init SDL Audio silently even if --disable-sound : */
677
678   if (audio_device == YES)
679     {
680       if (SDL_Init(SDL_INIT_AUDIO) < 0)
681         {
682           /* only print out message if sound or music
683              was not disabled at command-line
684            */
685           if (use_sound == YES || use_music == YES)
686             {
687               fprintf(stderr,
688                       "\nWarning: I could not initialize audio!\n"
689                       "The Simple DirectMedia error that occured was:\n"
690                       "%s\n\n", SDL_GetError());
691             }
692           /* keep the programming logic the same :-)
693              because in this case, use_sound & use_music' values are ignored
694              when there's no available audio device
695           */
696           use_sound = NO;
697           use_music = NO;
698           audio_device = NO;
699         }
700     }
701
702
703   /* Open sound silently regarless the value of "use_sound": */
704
705   if (audio_device == YES)
706     {
707       if (open_audio(44100, AUDIO_S16, 2, 2048) < 0)
708         {
709           /* only print out message if sound or music
710              was not disabled at command-line
711            */
712           if ((use_sound == YES) || (use_music == YES))
713             {
714               fprintf(stderr,
715                       "\nWarning: I could not set up audio for 44100 Hz "
716                       "16-bit stereo.\n"
717                       "The Simple DirectMedia error that occured was:\n"
718                       "%s\n\n", SDL_GetError());
719             }
720           use_sound = NO;
721           use_music = NO;
722           audio_device = NO;
723         }
724     }
725
726 }
727
728
729 /* --- SHUTDOWN --- */
730
731 void st_shutdown(void)
732 {
733   close_audio();
734   SDL_Quit();
735 }
736
737
738 /* --- ABORT! --- */
739
740 void st_abort(char * reason, char * details)
741 {
742   fprintf(stderr, "\nError: %s\n%s\n\n", reason, details);
743   st_shutdown();
744   exit(1);
745 }
746
747
748 /* Set Icon (private) */
749
750 void seticon(void)
751 {
752   int masklen;
753   Uint8 * mask;
754   SDL_Surface * icon;
755
756
757   /* Load icon into a surface: */
758
759   icon = IMG_Load(DATA_PREFIX "/images/icon.png");
760   if (icon == NULL)
761     {
762       fprintf(stderr,
763               "\nError: I could not load the icon image: %s\n"
764               "The Simple DirectMedia error that occured was:\n"
765               "%s\n\n", DATA_PREFIX "images/icon.png", SDL_GetError());
766       exit(1);
767     }
768
769
770   /* Create mask: */
771
772   masklen = (((icon -> w) + 7) / 8) * (icon -> h);
773   mask = (Uint8*) malloc(masklen * sizeof(Uint8));
774   memset(mask, 0xFF, masklen);
775
776
777   /* Set icon: */
778
779   SDL_WM_SetIcon(icon, mask);
780
781
782   /* Free icon surface & mask: */
783
784   free(mask);
785   SDL_FreeSurface(icon);
786 }
787
788
789 /* Parse command-line arguments: */
790
791 void parseargs(int argc, char * argv[])
792 {
793   int i;
794
795   /* Set defaults: */
796
797
798   debug_mode = NO;
799   use_fullscreen = NO;
800   show_fps = NO;
801   use_gl = NO;
802
803 #ifndef NOSOUND
804
805   use_sound = YES;
806   use_music = YES;
807   audio_device = YES;
808 #else
809
810   use_sound = NO;
811   use_music = NO;
812   audio_device = NO;
813 #endif
814
815   /* Parse arguments: */
816
817   for (i = 1; i < argc; i++)
818     {
819       if (strcmp(argv[i], "--fullscreen") == 0 ||
820           strcmp(argv[i], "-f") == 0)
821         {
822           /* Use full screen: */
823
824           use_fullscreen = YES;
825         }
826       else if (strcmp(argv[i], "--show-fps") == 0)
827         {
828           /* Use full screen: */
829
830           show_fps = YES;
831         }
832       else if (strcmp(argv[i], "--opengl") == 0 ||
833                strcmp(argv[i], "-gl") == 0)
834         {
835 #ifndef NOOPENGL
836           /* Use OpengGL: */
837
838           use_gl = YES;
839 #endif
840
841         }
842       else if (strcmp(argv[i], "--usage") == 0)
843         {
844           /* Show usage: */
845
846           usage(argv[0], 0);
847         }
848       else if (strcmp(argv[i], "--version") == 0)
849         {
850           /* Show version: */
851
852           printf("Super Tux - version " VERSION "\n");
853           exit(0);
854         }
855       else if (strcmp(argv[i], "--disable-sound") == 0)
856         {
857           /* Disable the compiled in sound feature */
858 #ifndef NOSOUND
859           printf("Sounds disabled \n");
860           use_sound = NO;
861 #else
862
863           printf("Warning: Sounds feature is not compiled in \n");
864 #endif
865
866         }
867       else if (strcmp(argv[i], "--disable-music") == 0)
868         {
869           /* Disable the compiled in sound feature */
870 #ifndef NOSOUND
871           printf("Music disabled \n");
872           use_music = NO;
873 #else
874
875           printf("Warning: Music feature is not compiled in \n");
876 #endif
877
878         }
879       else if (strcmp(argv[i], "--debug-mode") == 0)
880         {
881           /* Enable the debug-mode */
882           debug_mode = YES;
883
884         }
885       else if (strcmp(argv[i], "--help") == 0)
886         {         /* Show help: */
887
888           printf("Super Tux " VERSION "\n\n");
889
890           printf("----------  Command-line options  ----------\n\n");
891
892           printf("  --opengl            - If opengl support was compiled in, this will enable the EXPERIMENTAL OpenGL mode.\n\n");
893
894           printf("  --disable-sound     - If sound support was compiled in,  this will\n                        disable sound for this session of the game.\n\n");
895
896           printf("  --disable-music     - Like above, but this will disable music.\n\n");
897
898           printf("  --fullscreen        - Run in fullscreen mode.\n\n");
899
900           printf("  --debug-mode        - Enables the debug-mode, which is useful for developers.\n\n");
901
902           printf("  --help              - Display a help message summarizing command-line\n                        options, license and game controls.\n\n");
903
904           printf("  --usage             - Display a brief message summarizing command-line options.\n\n");
905
906           printf("  --version           - Display the version of SuperTux you're running.\n\n\n");
907
908
909           printf("----------          License       ----------\n\n");
910           printf("  This program comes with ABSOLUTELY NO WARRANTY.\n");
911           printf("  This is free software, and you are welcome to redistribute\n");
912           printf("  or modify it under certain conditions. See the file \n");
913           printf("  \"COPYING.txt\" for more details.\n\n\n");
914
915           printf("----------      Game controls     ----------\n\n");
916           printf("  Please see the file \"README.txt\"\n\n");
917
918           exit(0);
919         }
920       else
921         {
922           /* Unknown - complain! */
923
924           usage(argv[0], 1);
925         }
926     }
927 }
928
929
930 /* Display usage: */
931
932 void usage(char * prog, int ret)
933 {
934   FILE * fi;
935
936
937   /* Determine which stream to write to: */
938
939   if (ret == 0)
940     fi = stdout;
941   else
942     fi = stderr;
943
944
945   /* Display the usage message: */
946
947   fprintf(fi, "Usage: %s [--fullscreen] [--opengl] [--disable-sound] [--disable-music] [--debug-mode] | [--usage | --help | --version]\n",
948           prog);
949
950
951   /* Quit! */
952
953   exit(ret);
954 }
955