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