added scr_lvled, a bunch of libraries, and improved framework code
[raydungeon] / src / options.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include "options.h"
6 #include "treestor.h"
7
8 #define DEF_XRES                1280
9 #define DEF_YRES                800
10 #define DEF_VSYNC               1
11 #define DEF_VOL                 255
12 #define DEF_MUS                 1
13 #define DEF_FULLSCR             0
14 #define DEF_INVMOUSEY   0
15 #define DEF_MOUSE_SPEED 50
16
17
18 struct options opt = {
19         DEF_XRES, DEF_YRES,
20         DEF_VSYNC,
21         DEF_FULLSCR,
22         DEF_VOL, DEF_VOL, DEF_VOL,
23         DEF_MUS,
24         DEF_INVMOUSEY,
25         DEF_MOUSE_SPEED,
26 };
27
28 int parse_options(int argc, char **argv)
29 {
30         int i;
31         static const char *usage_fmt = "Usage: %s [options]\n"
32                 "Options:\n"
33                 " -screen <name>: select starting screen\n"
34                 " -h,-help: print usage information and exit\n\n";
35
36         for(i=1; i<argc; i++) {
37                 if(argv[i][0] == '-') {
38                         if(strcmp(argv[i], "-scr") == 0 || strcmp(argv[i], "-screen") == 0) {
39                                 if(!argv[++i]) {
40                                         fprintf(stderr, "%s must be followed by a screen name\n", argv[i - 1]);
41                                         return -1;
42                                 }
43                         } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
44                                 printf(usage_fmt, argv[0]);
45                                 exit(0);
46                         } else {
47                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
48                                 return -1;
49                         }
50                 } else {
51                         fprintf(stderr, "unexpected argument: %s\n", argv[i]);
52                         return -1;
53                 }
54         }
55
56         return 0;
57 }
58
59 int load_options(const char *fname)
60 {
61         struct ts_node *cfg;
62
63         if(!(cfg = ts_load(fname))) {
64                 return -1;
65         }
66         printf("loaded config: %s\n", fname);
67
68         opt.xres = ts_lookup_int(cfg, "options.video.xres", DEF_XRES);
69         opt.yres = ts_lookup_int(cfg, "options.video.yres", DEF_YRES);
70         opt.vsync = ts_lookup_int(cfg, "options.video.vsync", DEF_VSYNC);
71         opt.fullscreen = ts_lookup_int(cfg, "options.video.fullscreen", DEF_FULLSCR);
72
73         opt.vol_master = ts_lookup_int(cfg, "options.audio.volmaster", DEF_VOL);
74         opt.vol_mus = ts_lookup_int(cfg, "options.audio.volmusic", DEF_VOL);
75         opt.vol_sfx = ts_lookup_int(cfg, "options.audio.volsfx", DEF_VOL);
76         opt.music = ts_lookup_int(cfg, "options.audio.music", DEF_MUS);
77
78         opt.inv_mouse_y = ts_lookup_int(cfg, "options.controls.invmousey", DEF_INVMOUSEY);
79         opt.mouse_speed = ts_lookup_int(cfg, "options.controls.mousespeed", DEF_MOUSE_SPEED);
80
81         ts_free_tree(cfg);
82         return 0;
83 }
84
85 #define WROPT(lvl, fmt, val, defval) \
86         do { \
87                 int i; \
88                 for(i=0; i<lvl; i++) fputc('\t', fp); \
89                 if((val) == (defval)) { \
90                         fprintf(fp, fmt "\t# default\n", val); \
91                 } else { \
92                         fprintf(fp, fmt "\n", val); \
93                 } \
94         } while(0)
95
96 int save_options(const char *fname)
97 {
98         FILE *fp;
99
100         printf("writing config: %s\n", fname);
101
102         if(!(fp = fopen(fname, "wb"))) {
103                 fprintf(stderr, "failed to save options (%s): %s\n", fname, strerror(errno));
104         }
105         fprintf(fp, "options {\n");
106         fprintf(fp, "\tvideo {\n");
107         WROPT(2, "xres = %d", opt.xres, DEF_XRES);
108         WROPT(2, "yres = %d", opt.yres, DEF_YRES);
109         WROPT(2, "vsync = %d", opt.vsync, DEF_VSYNC);
110         WROPT(2, "fullscreen = %d", opt.fullscreen, DEF_FULLSCR);
111         fprintf(fp, "\t}\n");
112
113         fprintf(fp, "\taudio {\n");
114         WROPT(2, "volmaster = %d", opt.vol_master, DEF_VOL);
115         WROPT(2, "volmusic = %d", opt.vol_mus, DEF_VOL);
116         WROPT(2, "volsfx = %d", opt.vol_sfx, DEF_VOL);
117         WROPT(2, "music = %d", opt.music ? 1 : 0, DEF_MUS);
118         fprintf(fp, "\t}\n");
119
120         fprintf(fp, "\tcontrols {\n");
121         WROPT(2, "invmousey = %d", opt.inv_mouse_y, DEF_INVMOUSEY);
122         WROPT(2, "mousespeed = %d", opt.mouse_speed, DEF_MOUSE_SPEED);
123         fprintf(fp, "\t}\n");
124
125         fprintf(fp, "}\n");
126         fprintf(fp, "# v" "i:ts=4 sts=4 sw=4 noexpandtab:\n");
127
128         fclose(fp);
129         return 0;
130 }