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