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