1 /* Tower Toppler - Nebulus
2  * Copyright (C) 2000-2012  Andreas R�ver
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18 
19 #include "configuration.h"
20 #include <string.h>
21 #include <stdlib.h>
22 #include "keyb.h"
23 
24 static bool
str2bool(char * s)25 str2bool(char *s) {
26   if (s) {
27     if (!strcmp("yes", s) || !strcmp("true", s)) return true;
28     else return (atoi(s) != 0);
29   }
30   return false;
31 }
32 
parse(FILE * in)33 void configuration::parse(FILE * in) {
34   char line[201], param[201];
35 
36   while (!feof(in)) {
37     if (fscanf(in, "%200s%*[\t ]%200s\n", line, param) == 2) {
38 
39       config_data *t = first_data;
40 
41       while (t) {
42         if (strstr(line, t->cnf_name)) {
43           switch (t->cnf_typ) {
44           case CT_BOOL:
45             *(bool *)t->cnf_var = str2bool(param);
46             break;
47           case CT_STRING:
48             if (strlen(param) > 1) {
49               param[strlen(param)-1] = '\0';
50               strncpy((char *)t->cnf_var, param+1, t->maxlen);
51             }
52             break;
53           case CT_INT:
54             *(int *)t->cnf_var = atoi(param);
55             break;
56           case CT_KEY:
57             if (atoi(param) > 0)
58               key_redefine((ttkey)t->maxlen, (SDLKey)atoi(param));
59             break;
60           default: assert_msg(0, "Unknown config data type.");
61           }
62           break;
63         }
64         t = t->next;
65       }
66     }
67   }
68 }
69 
register_entry(const char * cnf_name,cnf_type cnf_typ,void * cnf_var,long maxlen)70 void configuration::register_entry(const char *cnf_name, cnf_type  cnf_typ, void *cnf_var, long maxlen) {
71   config_data *t = new config_data;
72 
73   t->next = first_data;
74   first_data = t;
75 
76   t->cnf_name = cnf_name;
77   t->cnf_typ = cnf_typ;
78   t->cnf_var = cnf_var;
79   t->maxlen = maxlen;
80 }
81 
82 #define CNF_BOOL(a,b) register_entry(a, CT_BOOL, b, 0)
83 #define CNF_CHAR(a,b,c) register_entry(a, CT_STRING, b, c)
84 #define CNF_INT(a,b) register_entry(a, CT_INT, b, 0)
85 #define CNF_KEY(a,b) register_entry(a, CT_KEY, NULL, b)
86 
configuration(FILE * glob,FILE * local)87 configuration::configuration(FILE *glob, FILE *local) {
88 
89   i_fullscreen = false;
90   i_nosound  = false;
91   i_use_water = true;
92   i_use_alpha_sprites = false;
93   i_use_alpha_layers = false;
94   i_use_alpha_font = false;
95   i_use_alpha_darkening = false;
96   i_use_full_scroller = true;
97   i_waves_type = waves_nonreflecting;
98   i_status_top = true;  /* is status line top or bottom of screen? */
99   i_editor_towerpagesize = -1;
100   i_editor_towerstarthei = -5;
101   i_curr_password[0] = 0;
102   i_start_lives = 3;
103   i_editor_towername[0] = 0;
104   i_debug_level = 0;
105   i_game_speed = DEFAULT_GAME_SPEED;
106   i_nobonus = false;
107 
108   first_data = 0;
109   need_save = (local == 0);
110 
111   CNF_BOOL( "fullscreen",          &i_fullscreen );
112   CNF_BOOL( "nosound",             &i_nosound );
113   CNF_BOOL( "nomusic",             &i_nomusic );
114   CNF_CHAR( "editor_towername",    &i_editor_towername, TOWERNAMELEN );
115   CNF_BOOL( "use_alpha_sprites",   &i_use_alpha_sprites );
116   CNF_BOOL( "use_alpha_font",      &i_use_alpha_font );
117   CNF_BOOL( "use_alpha_layers",    &i_use_alpha_layers );
118   CNF_BOOL( "use_alpha_darkening", &i_use_alpha_darkening );
119   CNF_BOOL( "use_full_scroller",   &i_use_full_scroller );
120   CNF_BOOL( "status_top",          &i_status_top );
121   CNF_INT(  "editor_pagesize",     &i_editor_towerpagesize );
122   CNF_INT(  "editor_towerstarthei",&i_editor_towerstarthei );
123   CNF_INT(  "waves_type",          &i_waves_type );
124   CNF_KEY(  "key_fire",             fire_key );
125   CNF_KEY(  "key_up",               up_key );
126   CNF_KEY(  "key_down",             down_key );
127   CNF_KEY(  "key_left",             left_key );
128   CNF_KEY(  "key_right",            right_key );
129   CNF_CHAR( "password",            &i_curr_password, PASSWORD_LEN );
130   CNF_INT(  "start_lives",         &i_start_lives );
131   CNF_INT(  "game_speed",          &i_game_speed);
132   CNF_BOOL( "nobonus",             &i_nobonus);
133 
134   if (glob) {
135     parse(glob);
136     fclose(glob);
137   }
138 
139   f = local;
140   if (f) parse(f);
141 
142   if (i_start_lives < 1) i_start_lives = 1;
143   else if (i_start_lives > 3) i_start_lives = 3;
144 
145   if (i_game_speed < 0) i_game_speed = 0;
146   else if (i_game_speed > MAX_GAME_SPEED) i_game_speed = MAX_GAME_SPEED;
147 }
148 
~configuration(void)149 configuration::~configuration(void) {
150 
151   if (need_save && !f)
152     f = create_local_config_file(".toppler.rc");
153   if (need_save && f)
154   {
155     fseek(f, 0, SEEK_SET);
156 
157     config_data *t = first_data;
158 
159     while(t) {
160       fprintf(f, "%s: ", t->cnf_name);
161 
162       switch (t->cnf_typ) {
163       case CT_BOOL:
164         fprintf(f, "%s", (*(bool *)t->cnf_var)?("yes"):("no"));
165         break;
166       case CT_STRING:
167         fprintf(f, "\"%s\"", (char *)(t->cnf_var));
168         break;
169       case CT_INT:
170         fprintf(f, "%i", *(int *)t->cnf_var);
171         break;
172       case CT_KEY:
173         fprintf(f, "%i", (int)key_conv2sdlkey((ttkey)t->maxlen, true));
174         break;
175       default: assert_msg(0, "Unknown config data type.");
176       }
177 
178       fprintf(f, "\n");
179 
180       t = t->next;
181     }
182   }
183   if (f) { fclose(f); f=NULL; }
184 
185   config_data *t = first_data;
186 
187   while (t) {
188     t = t->next;
189     delete first_data;
190     first_data = t;
191   }
192 }
193 
curr_password(char pwd[PASSWORD_LEN+1])194 void configuration::curr_password(char pwd[PASSWORD_LEN+1]) {
195   need_save = true;
196   strncpy(i_curr_password, pwd, PASSWORD_LEN);
197   i_curr_password[PASSWORD_LEN] = 0;
198 }
199 
editor_towername(char name[TOWERNAMELEN+1])200 void configuration::editor_towername(char name[TOWERNAMELEN+1]) {
201   need_save = true;
202   strncpy(i_editor_towername, name, TOWERNAMELEN);
203   i_editor_towername[TOWERNAMELEN] = 0;
204 }
205 
206 configuration config(open_local_config_file(".toppler.rc"), open_local_config_file(".toppler.rc"));
207