31bf697188e767644b279891d6b61ef47450ab9e
[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 - January 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 #include <SDL_opengl.h>
21
22 #ifdef LINUX
23 #include <pwd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <ctype.h>
27 #endif
28
29 #include "defines.h"
30 #include "globals.h"
31 #include "setup.h"
32 #include "screen.h"
33
34 /* Local function prototypes: */
35
36 void seticon(void);
37 void usage(char * prog, int ret);
38
39 /* Does the given file exist and is it accessible? */
40 int faccessible(char *filename)
41 {
42   struct stat filestat;
43   if (stat(filename, &filestat) == -1)
44     return NO;
45   else
46     return YES;
47 }
48
49
50 /* --- SETUP --- */
51
52 void st_directory_setup(void)
53 {
54
55   /* Set SuperTux configuration and save directories */
56
57   /* Get home directory (from $HOME variable)... if we can't determine it,
58      use the current directory ("."): */
59   char *home;
60   if (getenv("HOME") != NULL)
61     home = getenv("HOME");
62   else
63     home = ".";
64
65   st_dir = (char *) malloc(sizeof(char) * (strlen(home) +
66                            strlen("/.supertux") + 1));
67   strcpy(st_dir, home);
68   strcat(st_dir, "/.supertux");
69
70   st_save_dir = (char *) malloc(sizeof(char) * (strlen(st_dir) + strlen("/save") + 1));
71
72   strcpy(st_save_dir,st_dir);
73   strcat(st_save_dir,"/save");
74
75   /* Create them. In the case they exist it won't destroy anything. */
76 #ifdef LINUX
77
78   mkdir(st_dir, 0755);
79   mkdir(st_save_dir, 0755);
80 #else
81   #ifdef WIN32
82
83   mkdir(st_dir);
84   mkdir(st_save_dir);
85 #endif
86 #endif
87 }
88
89 void st_general_setup(void)
90 {
91   /* Seed random number generator: */
92
93   srand(SDL_GetTicks());
94
95   /* Load global images: */
96
97   letters_black = load_image(DATA_PREFIX "/images/status/letters-black.png",
98                              USE_ALPHA);
99
100   letters_gold = load_image(DATA_PREFIX "/images/status/letters-gold.png",
101                             USE_ALPHA);/*
102       if (tux_x < 0)
103         tux_x = 0;*/
104
105   letters_blue = load_image(DATA_PREFIX "/images/status/letters-blue.png",
106                             USE_ALPHA);
107
108   letters_red = load_image(DATA_PREFIX "/images/status/letters-red.png",
109                            USE_ALPHA);
110
111
112   /* Set icon image: */
113
114   seticon();
115
116 }
117
118 void st_video_setup(void)
119 {
120
121 if(screen != NULL)
122    SDL_FreeSurface(screen); 
123
124   /* Init SDL Video: */
125
126   if (SDL_Init(SDL_INIT_VIDEO) < 0)
127     {
128       fprintf(stderr,
129               "\nError: I could not initialize video!\n"
130               "The Simple DirectMedia error that occured was:\n"
131               "%s\n\n", SDL_GetError());
132       exit(1);
133     }
134
135   /* Open display: */
136
137   if(use_gl)
138   st_video_setup_gl();
139   else
140   st_video_setup_sdl();
141
142   /* Set window manager stuff: */
143
144   SDL_WM_SetCaption("Super Tux", "Super Tux");
145
146 }
147
148 void st_video_setup_sdl(void)
149 {
150   if (use_fullscreen == YES)
151     {
152       screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */
153       if (screen == NULL)
154         {
155           fprintf(stderr,
156                   "\nWarning: I could not set up fullscreen video for "
157                   "640x480 mode.\n"
158                   "The Simple DirectMedia error that occured was:\n"
159                   "%s\n\n", SDL_GetError());
160           use_fullscreen = NO;
161         }
162     }
163     else
164     {
165       screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF );
166
167       if (screen == NULL)
168         {
169           fprintf(stderr,
170                   "\nError: I could not set up video for 640x480 mode.\n"
171                   "The Simple DirectMedia error that occured was:\n"
172                   "%s\n\n", SDL_GetError());
173           exit(1);
174         }
175     }
176 }
177
178 void st_video_setup_gl(void)
179 {
180
181         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
182         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
183         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
184         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
185         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
186                 
187   if (use_fullscreen == YES)
188     {
189       screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL ) ; /* | SDL_HWSURFACE); */
190       if (screen == NULL)
191         {
192           fprintf(stderr,
193                   "\nWarning: I could not set up fullscreen video for "
194                   "640x480 mode.\n"
195                   "The Simple DirectMedia error that occured was:\n"
196                   "%s\n\n", SDL_GetError());
197           use_fullscreen = NO;
198         }
199     }
200     else
201     {
202       screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_OPENGL | SDL_OPENGLBLIT  );
203
204       if (screen == NULL)
205         {
206           fprintf(stderr,
207                   "\nError: I could not set up video for 640x480 mode.\n"
208                   "The Simple DirectMedia error that occured was:\n"
209                   "%s\n\n", SDL_GetError());
210           exit(1);
211         }
212     }
213     
214     /* Initialisierung von OpenGL * /
215         glViewport(0, 0, screen->w, screen->h);
216
217         glMatrixMode(GL_PROJECTION);
218         glLoadIdentity();
219         glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
220
221         glMatrixMode(GL_MODELVIEW);
222         glLoadIdentity();
223 */
224         /*
225          * Set up OpenGL for 2D rendering.
226          */
227         glDisable(GL_DEPTH_TEST);
228         glDisable(GL_CULL_FACE);
229
230         glViewport(0, 0, screen->w, screen->h);
231         glMatrixMode(GL_PROJECTION);
232         glLoadIdentity();
233         glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
234
235         glMatrixMode(GL_MODELVIEW);
236         glLoadIdentity();
237         glTranslatef(0.0f, 0.0f, 0.0f);
238 }
239
240 void st_joystick_setup(void)
241 {
242
243   /* Init Joystick: */
244
245 #ifdef JOY_YES
246   use_joystick = YES;
247
248   if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
249     {
250       fprintf(stderr, "Warning: I could not initialize joystick!\n"
251               "The Simple DirectMedia error that occured was:\n"
252               "%s\n\n", SDL_GetError());
253
254       use_joystick = NO;
255     }
256   else
257     {
258       /* Open joystick: */
259
260       if (SDL_NumJoysticks() <= 0)
261         {
262           fprintf(stderr, "Warning: No joysticks are available.\n");
263
264           use_joystick = NO;
265         }
266       else
267         {
268           js = SDL_JoystickOpen(0);
269
270           if (js == NULL)
271             {
272               fprintf(stderr, "Warning: Could not open joystick 1.\n"
273                       "The Simple DirectMedia error that occured was:\n"
274                       "%s\n\n", SDL_GetError());
275
276               use_joystick = NO;
277             }
278           else
279             {
280               /* Check for proper joystick configuration: */
281
282               if (SDL_JoystickNumAxes(js) < 2)
283                 {
284                   fprintf(stderr,
285                           "Warning: Joystick does not have enough axes!\n");
286
287                   use_joystick = NO;
288                 }
289               else
290                 {
291                   if (SDL_JoystickNumButtons(js) < 2)
292                     {
293                       fprintf(stderr,
294                               "Warning: "
295                               "Joystick does not have enough buttons!\n");
296
297                       use_joystick = NO;
298                     }
299                 }
300             }
301         }
302     }
303 #endif
304
305 }
306
307 void st_audio_setup(void)
308 {
309
310   /* Init SDL Audio silently even if --disable-sound : */
311
312   if (audio_device == YES)
313     {
314       if (SDL_Init(SDL_INIT_AUDIO) < 0)
315         {
316           /* only print out message if sound or music
317              was not disabled at command-line
318            */
319           if (use_sound == YES || use_music == YES)
320             {
321               fprintf(stderr,
322                       "\nWarning: I could not initialize audio!\n"
323                       "The Simple DirectMedia error that occured was:\n"
324                       "%s\n\n", SDL_GetError());
325             }
326           /* keep the programming logic the same :-)
327              because in this case, use_sound & use_music' values are ignored
328              when there's no available audio device
329           */
330           use_sound = NO;
331           use_music = NO;
332           audio_device = NO;
333         }
334     }
335
336
337   /* Open sound silently regarless the value of "use_sound": */
338
339   if (audio_device == YES)
340     {
341       if (open_audio(44100, AUDIO_S16, 2, 512) < 0)
342         {
343           /* only print out message if sound or music
344              was not disabled at command-line
345            */
346           if ((use_sound == YES) || (use_music == YES))
347             {
348               fprintf(stderr,
349                       "\nWarning: I could not set up audio for 44100 Hz "
350                       "16-bit stereo.\n"
351                       "The Simple DirectMedia error that occured was:\n"
352                       "%s\n\n", SDL_GetError());
353             }
354           use_sound = NO;
355           use_music = NO;
356           audio_device = NO;
357         }
358     }
359
360 }
361
362
363 /* --- SHUTDOWN --- */
364
365 void st_shutdown(void)
366 {
367   close_audio();
368   SDL_Quit();
369 }
370
371
372 /* --- ABORT! --- */
373
374 void st_abort(char * reason, char * details)
375 {
376   fprintf(stderr, "\nError: %s\n%s\n\n", reason, details);
377   st_shutdown();
378   exit(1);
379 }
380
381
382 /* Set Icon (private) */
383
384 void seticon(void)
385 {
386   int masklen;
387   Uint8 * mask;
388   SDL_Surface * icon;
389
390
391   /* Load icon into a surface: */
392
393   icon = IMG_Load(DATA_PREFIX "/images/icon.png");
394   if (icon == NULL)
395     {
396       fprintf(stderr,
397               "\nError: I could not load the icon image: %s\n"
398               "The Simple DirectMedia error that occured was:\n"
399               "%s\n\n", DATA_PREFIX "images/icon.png", SDL_GetError());
400       exit(1);
401     }
402
403
404   /* Create mask: */
405
406   masklen = (((icon -> w) + 7) / 8) * (icon -> h);
407   mask = malloc(masklen * sizeof(Uint8));
408   memset(mask, 0xFF, masklen);
409
410
411   /* Set icon: */
412
413   SDL_WM_SetIcon(icon, mask);
414
415
416   /* Free icon surface & mask: */
417
418   free(mask);
419   SDL_FreeSurface(icon);
420 }
421
422
423 /* Parse command-line arguments: */
424
425 void parseargs(int argc, char * argv[])
426 {
427   int i;
428
429
430   /* Set defaults: */
431
432   debug_mode = NO;
433   use_fullscreen = NO;
434 #ifndef NOSOUND
435
436   use_sound = YES;
437   use_music = YES;
438   audio_device = YES;
439 #else
440
441   use_sound = NO;
442   use_music = NO;
443   audio_device = NO;
444 #endif
445
446   /* Parse arguments: */
447
448   for (i = 1; i < argc; i++)
449     {
450       if (strcmp(argv[i], "--fullscreen") == 0 ||
451           strcmp(argv[i], "-f") == 0)
452         {
453           /* Use full screen: */
454
455           use_fullscreen = YES;
456         }
457       else if (strcmp(argv[i], "--opengl") == 0 ||
458           strcmp(argv[i], "-g") == 0)
459         {
460           /* Use full screen: */
461
462           use_gl = YES;
463         }
464       else if (strcmp(argv[i], "--usage") == 0)
465         {
466           /* Show usage: */
467
468           usage(argv[0], 0);
469         }
470       else if (strcmp(argv[i], "--version") == 0)
471         {
472           /* Show version: */
473
474           printf("Super Tux - version " VERSION "\n");
475           exit(0);
476         }
477       else if (strcmp(argv[i], "--disable-sound") == 0)
478         {
479           /* Disable the compiled in sound feature */
480 #ifndef NOSOUND
481           printf("Sounds disabled \n");
482           use_sound = NO;
483 #else
484
485           printf("Warning: Sounds feature is not compiled in \n");
486 #endif
487
488         }
489       else if (strcmp(argv[i], "--disable-music") == 0)
490         {
491           /* Disable the compiled in sound feature */
492 #ifndef NOSOUND
493           printf("Music disabled \n");
494           use_music = NO;
495 #else
496
497           printf("Warning: Music feature is not compiled in \n");
498 #endif
499
500         }
501       else if (strcmp(argv[i], "--debug-mode") == 0)
502         {
503           /* Enable the debug-mode */
504           debug_mode = YES;
505
506         }
507       else if (strcmp(argv[i], "--help") == 0)
508         {         /* Show help: */
509
510           printf("Super Tux " VERSION "\n\n");
511
512           printf("----------  Command-line options  ----------\n\n");
513
514           printf("  --disable-sound     - If sound support was compiled in,  this will\n                        disable sound for this session of the game.\n\n");
515
516           printf("  --disable-music     - Like above, but this will disable music.\n\n");
517
518           printf("  --fullscreen        - Run in fullscreen mode.\n\n");
519
520           printf("  --debug-mode        - Enables the debug-mode, which is useful for developers.\n\n");
521
522           printf("  --help              - Display a help message summarizing command-line\n                        options, license and game controls.\n\n");
523
524           printf("  --usage             - Display a brief message summarizing command-line options.\n\n");
525
526           printf("  --version           - Display the version of SuperTux you're running.\n\n\n");
527
528
529           printf("----------          License       ----------\n\n");
530           printf("  This program comes with ABSOLUTELY NO WARRANTY.\n");
531           printf("  This is free software, and you are welcome to redistribute\n");
532           printf("  or modify it under certain conditions. See the file \n");
533           printf("  \"COPYING.txt\" for more details.\n\n\n");
534
535           printf("----------      Game controls     ----------\n\n");
536           printf("  Please see the file \"README.txt\"\n\n");
537
538           exit(0);
539         }
540       else
541         {
542           /* Unknown - complain! */
543
544           usage(argv[0], 1);
545         }
546     }
547 }
548
549
550 /* Display usage: */
551
552 void usage(char * prog, int ret)
553 {
554   FILE * fi;
555
556
557   /* Determine which stream to write to: */
558
559   if (ret == 0)
560     fi = stdout;
561   else
562     fi = stderr;
563
564
565   /* Display the usage message: */
566
567   fprintf(fi, "Usage: %s [--fullscreen] [--disable-sound] [--disable-music] [--debug-mode] | [--usage | --help | --version]\n",
568           prog);
569
570
571   /* Quit! */
572
573   exit(ret);
574 }
575