e228309b2398b23f8a3f28d9d6dbad79157b7523
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
42 enum {NONE
, BYTE
, WORD
, DWORD
, STRING
, SW_ON
, SW_OFF
, FILES
, KEY
};
44 typedef struct cfg_t
{
56 static const cfg_t arg
[] = {
57 {"file", NULL
, FILES
},
58 {"cheat", &cheat
, SW_ON
},
59 {"vga", &shot_vga
, SW_ON
},
60 {"sndvol", &snd_vol
, WORD
},
61 {"musvol",&mus_vol
, WORD
},
62 // {"fullscr", &fullscreen, SW_ON},
63 // {"window", &fullscreen, SW_OFF},
64 {"mon", &nomon
, SW_OFF
},
65 // {"gamma", &gammaa, DWORD},
66 {"warp", &_warp
, BYTE
},
67 {"width", &SCRW
, DWORD
},
68 {"height", &SCRH
, DWORD
},
69 // {"config", NULL, cfg_file, STRING},
70 {NULL
, NULL
, NONE
} // end
73 static const cfg_t cfg
[] = {
74 {"screenshot", &shot_vga
, SW_ON
},
75 {"sound_volume", &snd_vol
, WORD
},
76 {"music_volume", &mus_vol
, WORD
},
77 // {"fullscreen", &fullscreen, SW_ON},
78 {"sky", &w_horiz
, SW_ON
},
79 // {"gamma", &gammaa, DWORD},
80 {"screen_width", &SCRW
, DWORD
},
81 {"screen_height", &SCRH
, DWORD
},
82 {"music_random", &music_random
, SW_ON
},
83 {"music_time", &music_time
, DWORD
},
84 {"music_fade", &music_fade
, DWORD
},
85 {"pl1_left", &pl1
.kl
, KEY
},
86 {"pl1_right",&pl1
.kr
, KEY
},
87 {"pl1_up", &pl1
.ku
, KEY
},
88 {"pl1_down", &pl1
.kd
, KEY
},
89 {"pl1_jump", &pl1
.kj
, KEY
},
90 {"pl1_fire", &pl1
.kf
, KEY
},
91 {"pl1_next", &pl1
.kwr
, KEY
},
92 {"pl1_prev", &pl1
.kwl
, KEY
},
93 {"pl1_use", &pl1
.kp
, KEY
},
94 {"pl2_left", &pl2
.kl
, KEY
},
95 {"pl2_right",&pl2
.kr
, KEY
},
96 {"pl2_up", &pl2
.ku
, KEY
},
97 {"pl2_down", &pl2
.kd
, KEY
},
98 {"pl2_jump", &pl2
.kj
, KEY
},
99 {"pl2_fire", &pl2
.kf
, KEY
},
100 {"pl2_next", &pl2
.kwr
, KEY
},
101 {"pl2_prev", &pl2
.kwl
, KEY
},
102 {"pl2_use", &pl2
.kp
, KEY
},
103 {NULL
, NULL
, NONE
} // end
106 static const cfg_t
*CFG_find_entry (const char *key
, const cfg_t
*cfg
) {
110 while (cfg
[i
].cfg
&& strcasecmp(cfg
[i
].cfg
, key
) != 0) {
113 return cfg
[i
].cfg
? &cfg
[i
] : NULL
;
116 static int CFG_update_key (const char *key
, const char *value
, const cfg_t
*cfg
) {
117 const cfg_t
*entry
= CFG_find_entry(key
, cfg
);
121 case BYTE
: *(byte
*)p
= atoi(value
); break;
122 case WORD
: *(word
*)p
= atoi(value
); break;
123 case DWORD
: *(dword
*)p
= atoi(value
); break;
124 case STRING
: strcpy(p
, value
); break; // TODO fix this security problem
125 case SW_ON
: *(byte
*)p
= strcasecmp(value
, "on") == 0 ? 1 : 0; break;
126 case SW_OFF
: *(byte
*)p
= strcasecmp(value
, "off") == 0 ? 0 : 1; break;
127 case FILES
: F_addwad(value
); break;
128 case KEY
: *(int*)p
= I_string_to_key(value
); break;
129 default: assert(0); // unknown type -> something broken
139 static int CFG_open_iterator (const char *name
) {
141 f
= fopen(name
, "rb");
148 static void CFG_skip_space (void) {
149 while (feof(f
) == 0 && isspace(ch
)) {
154 static void CFG_skip_line (void) {
155 while (feof(f
) == 0 && ch
!= '\n' && ch
!= '\r') {
158 while (feof(f
) == 0 && ch
== '\n' && ch
== '\r') {
163 static int CFG_scan_iterator (char *key
, int keylen
, char *value
, int valuelen
) {
166 assert(value
!= NULL
);
167 assert(valuelen
> 0);
170 while (feof(f
) == 0 && found
== 0) {
174 } else if (feof(f
) == 0) {
177 while (feof(f
) == 0 && isspace(ch
) == 0 && ch
!= '=') {
178 if (i
< keylen
- 1) {
186 if (feof(f
) == 0 && ch
== '=') {
191 while (feof(f
) == 0 && ch
!= '\n' && ch
!= '\r') {
192 if (i
< valuelen
- 1) {
205 static void CFG_close_iterator (void) {
213 static int CFG_read_config (const char *name
) {
216 assert(name
!= NULL
);
217 if (CFG_open_iterator(name
)) {
218 while (CFG_scan_iterator(key
, 64, value
, 64)) {
219 CFG_update_key(key
, value
, cfg
);
221 CFG_close_iterator();
228 void CFG_args (int argc
, const char **argv
) {
230 for (i
= 1; i
< argc
; i
++) {
231 if (argv
[i
][0] == '-' && argv
[i
][1] != 0) {
233 ERR_failinit("CFG_args: not enough arguments for parameter %s\n", argv
[i
]);
235 if (CFG_update_key(&argv
[i
][1], argv
[i
+ 1], arg
) != 0) {
236 ERR_failinit("CFG_args: unknown parameter %s\n", argv
[i
]);
241 ERR_failinit("CFG_args: something wrong here: %s\n", argv
[i
]);
246 void CFG_load (void) {
247 CFG_read_config("default.cfg");
248 CFG_read_config("doom2d.cfg");
253 static void CFG_write_key_value (FILE *f
, const char *key
, const char *value
) {
256 assert(value
!= NULL
);
257 fwrite(key
, strlen(key
), 1, f
);
258 fwrite("=", 1, 1, f
);
259 fwrite(value
, strlen(value
), 1, f
);
260 fwrite("\n", 1, 1, f
);
263 static int CFG_write_entry (FILE *f
, const cfg_t
*entry
) {
265 assert(entry
!= NULL
);
268 const char *key
= entry
->cfg
;
272 snprintf(buf
, 64, "%i", *(byte
*)entry
->p
);
273 CFG_write_key_value(f
, key
, buf
);
276 snprintf(buf
, 64, "%i", *(word
*)entry
->p
);
277 CFG_write_key_value(f
, key
, buf
);
280 snprintf(buf
, 64, "%i", *(dword
*)entry
->p
);
281 CFG_write_key_value(f
, key
, buf
);
284 CFG_write_key_value(f
, key
, entry
->p
);
288 str
= *(byte
*)entry
->p
? "on" : "off";
289 CFG_write_key_value(f
, key
, str
);
292 str
= I_key_to_string(*(int*)entry
->p
);
293 CFG_write_key_value(f
, key
, str
);
295 case FILES
: return 1; // ignore
296 case NONE
: return 0; // end
297 default: assert(0); // unknown type -> something broken
300 return entry
->t
== NONE
? 0 : 1;
303 static int CFG_update_config (const char *old
, const char *new, const cfg_t
*cfg
, const char *msg
) {
309 FILE *nf
= fopen(new, "wb");
312 fwrite("; ", 2, 1, nf
);
313 fwrite(msg
, strlen(msg
), 1, nf
);
314 fwrite("\n", 1, 1, nf
);
316 if (CFG_open_iterator(old
)) {
317 while (CFG_scan_iterator(key
, 64, value
, 64)) {
318 if (CFG_find_entry(key
, cfg
) == NULL
) {
319 CFG_write_key_value(nf
, key
, value
);
322 CFG_close_iterator();
325 while (CFG_write_entry(nf
, &cfg
[i
])) {
333 void CFG_save (void) {
334 CFG_update_config("doom2d.cfg", "doom2d.cfg", cfg
, "generated by doom2d, do not modify");
335 //CFG_update_config("doom2d.cfg", "doom2d.tmp", cfg, "temporary file");
336 //CFG_update_config("doom2d.tmp", "doom2d.cfg", cfg, "generated by doom2d, do not modify");
337 //remove("doom2d.tmp");