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