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