moved savelevel() code to level.h/c where it belongs to. :)
[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/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  text_load(&black_text,DATA_PREFIX "/images/status/letters-black.png");
101  text_load(&gold_text,DATA_PREFIX "/images/status/letters-gold.png");
102  text_load(&blue_text,DATA_PREFIX "/images/status/letters-blue.png");
103  text_load(&red_text,DATA_PREFIX "/images/status/letters-red.png");
104  
105   /* Set icon image: */
106
107   seticon();
108   SDL_EnableUNICODE(1);
109
110 }
111
112 void st_video_setup(void)
113 {
114
115 if(screen != NULL)
116    SDL_FreeSurface(screen); 
117
118   /* Init SDL Video: */
119
120   if (SDL_Init(SDL_INIT_VIDEO) < 0)
121     {
122       fprintf(stderr,
123               "\nError: I could not initialize video!\n"
124               "The Simple DirectMedia error that occured was:\n"
125               "%s\n\n", SDL_GetError());
126       exit(1);
127     }
128
129   /* Open display: */
130
131   if(use_gl)
132   st_video_setup_gl();
133   else
134   st_video_setup_sdl();
135   
136   texture_setup();
137     
138   /* Set window manager stuff: */
139
140   SDL_WM_SetCaption("Super Tux", "Super Tux");
141
142 }
143
144 void st_video_setup_sdl(void)
145 {
146   if (use_fullscreen == YES)
147     {
148       screen = SDL_SetVideoMode(640, 480, 16, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */
149       if (screen == NULL)
150         {
151           fprintf(stderr,
152                   "\nWarning: I could not set up fullscreen video for "
153                   "640x480 mode.\n"
154                   "The Simple DirectMedia error that occured was:\n"
155                   "%s\n\n", SDL_GetError());
156           use_fullscreen = NO;
157         }
158     }
159     else
160     {
161       screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE | SDL_DOUBLEBUF );
162
163       if (screen == NULL)
164         {
165           fprintf(stderr,
166                   "\nError: I could not set up video for 640x480 mode.\n"
167                   "The Simple DirectMedia error that occured was:\n"
168                   "%s\n\n", SDL_GetError());
169           exit(1);
170         }
171     }
172 }
173
174 void st_video_setup_gl(void)
175 {
176 #ifndef NOOPENGL
177
178         SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
179         SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
180         SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
181         SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
182         SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
183
184   if (use_fullscreen == YES)
185     {
186       screen = SDL_SetVideoMode(640, 480, 32, SDL_FULLSCREEN | SDL_OPENGL ) ; /* | SDL_HWSURFACE); */
187       if (screen == NULL)
188         {
189           fprintf(stderr,
190                   "\nWarning: I could not set up fullscreen video for "
191                   "640x480 mode.\n"
192                   "The Simple DirectMedia error that occured was:\n"
193                   "%s\n\n", SDL_GetError());
194           use_fullscreen = NO;
195         }
196     }
197     else
198     {
199       screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_OPENGL | SDL_OPENGLBLIT  );
200
201       if (screen == NULL)
202         {
203           fprintf(stderr,
204                   "\nError: I could not set up video for 640x480 mode.\n"
205                   "The Simple DirectMedia error that occured was:\n"
206                   "%s\n\n", SDL_GetError());
207           exit(1);
208         }
209     }
210         
211         /*
212          * Set up OpenGL for 2D rendering.
213          */
214         glDisable(GL_DEPTH_TEST);
215         glDisable(GL_CULL_FACE);
216
217         glViewport(0, 0, screen->w, screen->h);
218         glMatrixMode(GL_PROJECTION);
219         glLoadIdentity();
220         glOrtho(0, screen->w, screen->h, 0, -1.0, 1.0);
221
222         glMatrixMode(GL_MODELVIEW);
223         glLoadIdentity();
224         glTranslatef(0.0f, 0.0f, 0.0f);
225         
226 #endif
227 }
228
229 void st_joystick_setup(void)
230 {
231
232   /* Init Joystick: */
233
234 #ifdef JOY_YES
235   use_joystick = YES;
236
237   if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
238     {
239       fprintf(stderr, "Warning: I could not initialize joystick!\n"
240               "The Simple DirectMedia error that occured was:\n"
241               "%s\n\n", SDL_GetError());
242
243       use_joystick = NO;
244     }
245   else
246     {
247       /* Open joystick: */
248
249       if (SDL_NumJoysticks() <= 0)
250         {
251           fprintf(stderr, "Warning: No joysticks are available.\n");
252
253           use_joystick = NO;
254         }
255       else
256         {
257           js = SDL_JoystickOpen(0);
258
259           if (js == NULL)
260             {
261               fprintf(stderr, "Warning: Could not open joystick 1.\n"
262                       "The Simple DirectMedia error that occured was:\n"
263                       "%s\n\n", SDL_GetError());
264
265               use_joystick = NO;
266             }
267           else
268             {
269               /* Check for proper joystick configuration: */
270
271               if (SDL_JoystickNumAxes(js) < 2)
272                 {
273                   fprintf(stderr,
274                           "Warning: Joystick does not have enough axes!\n");
275
276                   use_joystick = NO;
277                 }
278               else
279                 {
280                   if (SDL_JoystickNumButtons(js) < 2)
281                     {
282                       fprintf(stderr,
283                               "Warning: "
284                               "Joystick does not have enough buttons!\n");
285
286                       use_joystick = NO;
287                     }
288                 }
289             }
290         }
291     }
292 #endif
293
294 }
295
296 void st_audio_setup(void)
297 {
298
299   /* Init SDL Audio silently even if --disable-sound : */
300
301   if (audio_device == YES)
302     {
303       if (SDL_Init(SDL_INIT_AUDIO) < 0)
304         {
305           /* only print out message if sound or music
306              was not disabled at command-line
307            */
308           if (use_sound == YES || use_music == YES)
309             {
310               fprintf(stderr,
311                       "\nWarning: I could not initialize audio!\n"
312                       "The Simple DirectMedia error that occured was:\n"
313                       "%s\n\n", SDL_GetError());
314             }
315           /* keep the programming logic the same :-)
316              because in this case, use_sound & use_music' values are ignored
317              when there's no available audio device
318           */
319           use_sound = NO;
320           use_music = NO;
321           audio_device = NO;
322         }
323     }
324
325
326   /* Open sound silently regarless the value of "use_sound": */
327
328   if (audio_device == YES)
329     {
330       if (open_audio(44100, AUDIO_S16, 2, 2048) < 0)
331         {
332           /* only print out message if sound or music
333              was not disabled at command-line
334            */
335           if ((use_sound == YES) || (use_music == YES))
336             {
337               fprintf(stderr,
338                       "\nWarning: I could not set up audio for 44100 Hz "
339                       "16-bit stereo.\n"
340                       "The Simple DirectMedia error that occured was:\n"
341                       "%s\n\n", SDL_GetError());
342             }
343           use_sound = NO;
344           use_music = NO;
345           audio_device = NO;
346         }
347     }
348
349 }
350
351
352 /* --- SHUTDOWN --- */
353
354 void st_shutdown(void)
355 {
356   close_audio();
357   SDL_Quit();
358 }
359
360
361 /* --- ABORT! --- */
362
363 void st_abort(char * reason, char * details)
364 {
365   fprintf(stderr, "\nError: %s\n%s\n\n", reason, details);
366   st_shutdown();
367   exit(1);
368 }
369
370
371 /* Set Icon (private) */
372
373 void seticon(void)
374 {
375   int masklen;
376   Uint8 * mask;
377   SDL_Surface * icon;
378
379
380   /* Load icon into a surface: */
381
382   icon = IMG_Load(DATA_PREFIX "/images/icon.png");
383   if (icon == NULL)
384     {
385       fprintf(stderr,
386               "\nError: I could not load the icon image: %s\n"
387               "The Simple DirectMedia error that occured was:\n"
388               "%s\n\n", DATA_PREFIX "images/icon.png", SDL_GetError());
389       exit(1);
390     }
391
392
393   /* Create mask: */
394
395   masklen = (((icon -> w) + 7) / 8) * (icon -> h);
396   mask = malloc(masklen * sizeof(Uint8));
397   memset(mask, 0xFF, masklen);
398
399
400   /* Set icon: */
401
402   SDL_WM_SetIcon(icon, mask);
403
404
405   /* Free icon surface & mask: */
406
407   free(mask);
408   SDL_FreeSurface(icon);
409 }
410
411
412 /* Parse command-line arguments: */
413
414 void parseargs(int argc, char * argv[])
415 {
416   int i;
417
418   /* Set defaults: */
419
420
421   debug_mode = NO;
422   use_fullscreen = NO;
423   show_fps = NO;
424   use_gl = NO;    
425
426 #ifndef NOSOUND
427
428   use_sound = YES;
429   use_music = YES;
430   audio_device = YES;
431 #else
432
433   use_sound = NO;
434   use_music = NO;
435   audio_device = NO;
436 #endif
437
438   /* Parse arguments: */
439
440   for (i = 1; i < argc; i++)
441     {
442       if (strcmp(argv[i], "--fullscreen") == 0 ||
443           strcmp(argv[i], "-f") == 0)
444         {
445           /* Use full screen: */
446
447           use_fullscreen = YES;
448         }
449       else if (strcmp(argv[i], "--show-fps") == 0)
450         {
451           /* Use full screen: */
452
453           show_fps = YES;
454         }
455       else if (strcmp(argv[i], "--opengl") == 0 ||
456           strcmp(argv[i], "-gl") == 0)
457         {
458         #ifndef NOOPENGL
459           /* Use OpengGL: */
460
461           use_gl = YES;
462         #endif
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("  --opengl            - If opengl support was compiled in, this will enable the EXPERIMENTAL OpenGL mode.\n\n");
515           
516           printf("  --disable-sound     - If sound support was compiled in,  this will\n                        disable sound for this session of the game.\n\n");
517
518           printf("  --disable-music     - Like above, but this will disable music.\n\n");
519
520           printf("  --fullscreen        - Run in fullscreen mode.\n\n");
521
522           printf("  --debug-mode        - Enables the debug-mode, which is useful for developers.\n\n");
523
524           printf("  --help              - Display a help message summarizing command-line\n                        options, license and game controls.\n\n");
525
526           printf("  --usage             - Display a brief message summarizing command-line options.\n\n");
527
528           printf("  --version           - Display the version of SuperTux you're running.\n\n\n");
529
530
531           printf("----------          License       ----------\n\n");
532           printf("  This program comes with ABSOLUTELY NO WARRANTY.\n");
533           printf("  This is free software, and you are welcome to redistribute\n");
534           printf("  or modify it under certain conditions. See the file \n");
535           printf("  \"COPYING.txt\" for more details.\n\n\n");
536
537           printf("----------      Game controls     ----------\n\n");
538           printf("  Please see the file \"README.txt\"\n\n");
539
540           exit(0);
541         }
542       else
543         {
544           /* Unknown - complain! */
545
546           usage(argv[0], 1);
547         }
548     }
549 }
550
551
552 /* Display usage: */
553
554 void usage(char * prog, int ret)
555 {
556   FILE * fi;
557
558
559   /* Determine which stream to write to: */
560
561   if (ret == 0)
562     fi = stdout;
563   else
564     fi = stderr;
565
566
567   /* Display the usage message: */
568
569   fprintf(fi, "Usage: %s [--fullscreen] [--opengl] [--disable-sound] [--disable-music] [--debug-mode] | [--usage | --help | --version]\n",
570           prog);
571
572
573   /* Quit! */
574
575   exit(ret);
576 }
577