move over rewritten lispreader from tuxkart (with additional fixes), generalized...
[supertux.git] / lib / utils / configfile.cpp
1 //  $Id$
2 //
3 //  SuperTux -  A Jump'n Run
4 //  Copyright (C) 2004 Michael George <mike@georgetech.com>
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 2
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
20 #include <config.h>
21
22 #include <cstdlib>
23 #include <string>
24 #include <stdexcept>
25
26 #include "configfile.h"
27 #include "app/setup.h"
28 #include "app/globals.h"
29 #include "audio/sound_manager.h"
30 #include "lisp/parser.h"
31
32 using namespace SuperTux;
33
34 #ifdef WIN32
35 const char * config_filename = ("/"+ package_symbol_name + "_config.dat").c_str();
36 #else
37 const char * config_filename = "/config";
38 #endif
39
40 Config* SuperTux::config = 0;
41
42 static void defaults ()
43 {
44   /* Set defaults: */
45   debug_mode = false;
46   SoundManager::get()->set_audio_device_available(true);
47
48   use_fullscreen = false;
49   show_fps = false;
50   use_gl = false;
51
52   SoundManager::get()->enable_sound(true);
53   SoundManager::get()->enable_music(true);
54 }
55
56 FILE * SuperTux::opendata(const std::string& rel_filename, const char *mode)
57 {
58   std::string filename;
59   FILE * fi;
60
61   filename = st_dir + rel_filename;
62
63   /* Try opening the file: */
64   fi = fopen(filename.c_str(), mode);
65
66   if (fi == NULL)
67     {
68       fprintf(stderr, "Warning: Unable to open the file \"%s\" ", filename.c_str());
69
70       if (strcmp(mode, "r") == 0)
71         fprintf(stderr, "for read!!!\n");
72       else if (strcmp(mode, "w") == 0)
73         fprintf(stderr, "for write!!!\n");
74     }
75
76   return(fi);
77 }
78
79 void Config::load()
80 {
81   defaults();
82
83   lisp::Parser parser;
84   try {
85     std::auto_ptr<lisp::Lisp> root (parser.parse(st_dir + config_filename));
86
87     const lisp::Lisp* config_lisp = root->get_lisp(
88         package_symbol_name + "-config");
89     if(!config_lisp)
90       throw new std::runtime_error("Config file is not a supertux-config file");
91
92     config_lisp->get("fullscreen", use_fullscreen);
93     bool temp = false;
94     if(config_lisp->get("sound", temp))
95       SoundManager::get()->enable_sound(temp);
96     if(config_lisp->get("music", temp))
97       SoundManager::get()->enable_music(temp);
98     config_lisp->get("show_fps",   show_fps);
99
100     std::string video;
101     if(config_lisp->get("video", video)) {
102       if (video == "opengl")
103         use_gl = true;
104       else
105         use_gl = false;
106     }
107
108     joystick_num = 0;
109     config_lisp->get("joystick", joystick_num);
110     
111     if (joystick_num >= 0) {
112       config_lisp->get("joystick-x", joystick_keymap.x_axis);
113       config_lisp->get("joystick-y", joystick_keymap.y_axis);
114       config_lisp->get("joystick-a", joystick_keymap.a_button);
115       config_lisp->get("joystick-b", joystick_keymap.b_button);
116       config_lisp->get("joystick-start", joystick_keymap.start_button);
117       config_lisp->get("joystick-deadzone", joystick_keymap.dead_zone);
118     }
119
120     customload(config_lisp);
121   } catch(std::exception& e) {
122     std::cerr << "Couldn't load configfile: " << e.what() << "\n";
123   }
124 }
125
126 void Config::save ()
127 {
128   /* write settings to config file */
129   FILE * config = opendata(config_filename, "w");
130
131   if(config)
132     {
133       fprintf(config, ("("+package_symbol_name+"-config\n").c_str());
134       fprintf(config, "\t;; the following options can be set to #t or #f:\n");
135       fprintf(config, "\t(fullscreen %s)\n", use_fullscreen ? "#t" : "#f");
136       fprintf(config, "\t(sound      %s)\n", SoundManager::get()->sound_enabled()      ? "#t" : "#f");
137       fprintf(config, "\t(music      %s)\n", SoundManager::get()->music_enabled()      ? "#t" : "#f");
138       fprintf(config, "\t(show_fps   %s)\n", show_fps       ? "#t" : "#f");
139
140       fprintf(config, "\n\t;; either \"opengl\" or \"sdl\"\n");
141       fprintf(config, "\t(video      \"%s\")\n", use_gl ? "opengl" : "sdl");
142
143       if(use_joystick)
144         {
145         fprintf(config, "\n\t;; joystick number:\n");
146         fprintf(config, "\t(joystick   %d)\n", joystick_num);
147
148         fprintf(config, "\t(joystick-x   %d)\n", joystick_keymap.x_axis);
149         fprintf(config, "\t(joystick-y   %d)\n", joystick_keymap.y_axis);
150         fprintf(config, "\t(joystick-a   %d)\n", joystick_keymap.a_button);
151         fprintf(config, "\t(joystick-b   %d)\n", joystick_keymap.b_button);
152         fprintf(config, "\t(joystick-start  %d)\n", joystick_keymap.start_button);
153         fprintf(config, "\t(joystick-deadzone  %d)\n", joystick_keymap.dead_zone);
154         }
155         
156         customsave(config);
157
158       fprintf(config, ")\n");
159       fclose(config);
160     }
161 }
162