1 // Evil and Nasty Configuration File Reader for KenBuild
2 // by Jonathon Fowler
3 
4 #include "build.h"
5 #include "editor.h"
6 #include "osd.h"
7 #include "scriptfile.h"
8 
9 #ifdef RENDERTYPEWIN
10 #include "winlayer.h"
11 #endif
12 #include "baselayer.h"
13 
14 static int vesares[13][2] = {{320,200},{360,200},{320,240},{360,240},{320,400},
15 				{360,400},{640,350},{640,400},{640,480},{800,600},
16 				{1024,768},{1280,1024},{1600,1200}};
17 
18 extern short brightness;
19 extern int fullscreen;
20 extern char option[8];
21 extern int keys[NUMBUILDKEYS];
22 extern double msens;
23 
24 /*
25  * SETUP.DAT
26  * 0      = video mode (0:chained 1:vesa 2:screen buffered 3/4/5:tseng/paradise/s3 6:red-blue)
27  * 1      = sound (0:none)
28  * 2      = music (0:none)
29  * 3      = input (0:keyboard 1:+mouse)
30  * 4      = multiplayer (0:single 1-4:com 5-11:ipx)
31  * 5&0xf0 = com speed
32  * 5&0x0f = com irq
33  * 6&0xf0 = chained y-res
34  * 6&0x0f = chained x-res or vesa mode
35  * 7&0xf0 = sound samplerate
36  * 7&0x01 = sound quality
37  * 7&0x02 = 8/16 bit
38  * 7&0x04 = mono/stereo
39  *
40  * bytes 8 to 26 are key settings:
41  * 0      = Forward (0xc8)
42  * 1      = Backward (0xd0)
43  * 2      = Turn left (0xcb)
44  * 3      = Turn right (0xcd)
45  * 4      = Run (0x2a)
46  * 5      = Strafe (0x9d)
47  * 6      = Fire (0x1d)
48  * 7      = Use (0x39)
49  * 8      = Stand high (0x1e)
50  * 9      = Stand low (0x2c)
51  * 10     = Look up (0xd1)
52  * 11     = Look down (0xc9)
53  * 12     = Strafe left (0x33)
54  * 13     = Strafe right (0x34)
55  * 14     = 2D/3D switch (0x9c)
56  * 15     = View cycle (0x1c)
57  * 16     = 2D Zoom in (0xd)
58  * 17     = 2D Zoom out (0xc)
59  * 18     = Chat (0xf)
60  */
61 
62 enum {
63 	type_bool = 0,	//int
64 	type_double = 1,
65 	type_int = 2,
66 	type_hex = 3,
67 };
68 
69 static int tmprenderer = -1;
70 static int tmpbrightness = -1;
71 
72 static struct {
73 	const char *name;
74 	int type;
75 	void *store;
76 	const char *doc;
77 } configspec[] = {
78 	{ "forcesetup", type_bool, &forcesetup,
79 		"; Always show configuration options on startup\n"
80 		";   0 - No\n"
81 		";   1 - Yes\n"
82     },
83 	{ "fullscreen", type_bool, &fullscreen,
84 		"; Video mode selection\n"
85 		";   0 - Windowed\n"
86 		";   1 - Fullscreen\n"
87 	},
88 	{ "xdim2d", type_int, &xdim2d,
89 		"; Video resolution\n"
90 	},
91 	{ "ydim2d", type_int, &ydim2d, NULL },
92 	{ "xdim3d", type_int, &xdimgame, NULL },
93 	{ "ydim3d", type_int, &ydimgame, NULL },
94 	{ "bpp",    type_int, &bppgame,
95 		"; 3D-mode colour depth\n"
96 	},
97 #if USE_POLYMOST
98 	{ "renderer", type_int, &tmprenderer,
99 		"; 3D-mode renderer type\n"
100 		";   0  - classic\n"
101 		";   2  - software Polymost\n"
102 		";   3  - OpenGL Polymost\n"
103 	},
104 #endif
105 	{ "brightness", type_int, &tmpbrightness,
106 		"; 3D mode brightness setting\n"
107 		";   0  - lowest\n"
108 		";   15 - highest\n"
109 	},
110 #if USE_POLYMOST && USE_OPENGL
111 	{ "glusetexcache", type_bool, &glusetexcache,
112 		"; OpenGL mode options\n"
113 	},
114 #endif
115 #ifdef RENDERTYPEWIN
116 	{ "maxrefreshfreq", type_int, &maxrefreshfreq,
117 		"; Maximum OpenGL mode refresh rate (Windows only, in Hertz)\n"
118 	},
119 #endif
120 	{ "mousesensitivity", type_double, &msens,
121 		"; Mouse sensitivity\n"
122 	},
123 	{ "keyforward", type_hex, &keys[0],
124 		"; Key Settings\n"
125 		";  Here's a map of all the keyboard scan codes: NOTE: values are listed in hex!\n"
126 		"; +---------------------------------------------------------------------------------------------+\n"
127 		"; | 01   3B  3C  3D  3E   3F  40  41  42   43  44  57  58          46                           |\n"
128 		"; |ESC   F1  F2  F3  F4   F5  F6  F7  F8   F9 F10 F11 F12        SCROLL                         |\n"
129 		"; |                                                                                             |\n"
130 		"; |29  02  03  04  05  06  07  08  09  0A  0B  0C  0D   0E     D2  C7  C9      45  B5  37  4A   |\n"
131 		"; | ` '1' '2' '3' '4' '5' '6' '7' '8' '9' '0'  -   =  BACK    INS HOME PGUP  NUMLK KP/ KP* KP-  |\n"
132 		"; |                                                                                             |\n"
133 		"; | 0F  10  11  12  13  14  15  16  17  18  19  1A  1B  2B     D3  CF  D1      47  48  49  4E   |\n"
134 		"; |TAB  Q   W   E   R   T   Y   U   I   O   P   [   ]    \\    DEL END PGDN    KP7 KP8 KP9 KP+   |\n"
135 		"; |                                                                                             |\n"
136 		"; | 3A   1E  1F  20  21  22  23  24  25  26  27  28     1C                     4B  4C  4D       |\n"
137 		"; |CAPS  A   S   D   F   G   H   J   K   L   ;   '   ENTER                    KP4 KP5 KP6    9C |\n"
138 		"; |                                                                                      KPENTER|\n"
139 		"; |  2A    2C  2D  2E  2F  30  31  32  33  34  35    36            C8          4F  50  51       |\n"
140 		"; |LSHIFT  Z   X   C   V   B   N   M   ,   .   /   RSHIFT          UP         KP1 KP2 KP3       |\n"
141 		"; |                                                                                             |\n"
142 		"; | 1D     38              39                  B8     9D       CB  D0   CD      52    53        |\n"
143 		"; |LCTRL  LALT           SPACE                RALT   RCTRL   LEFT DOWN RIGHT    KP0    KP.      |\n"
144 		"; +---------------------------------------------------------------------------------------------+\n"
145 	},
146 	{ "keybackward", type_hex, &keys[1], NULL },
147 	{ "keyturnleft", type_hex, &keys[2], NULL },
148 	{ "keyturnright", type_hex, &keys[3], NULL },
149 	{ "keyrun", type_hex, &keys[4], NULL },
150 	{ "keystrafe", type_hex, &keys[5], NULL },
151 	{ "keyfire", type_hex, &keys[6], NULL },
152 	{ "keyuse", type_hex, &keys[7], NULL },
153 	{ "keystandhigh", type_hex, &keys[8], NULL },
154 	{ "keystandlow", type_hex, &keys[9], NULL },
155 	{ "keylookup", type_hex, &keys[10], NULL },
156 	{ "keylookdown", type_hex, &keys[11], NULL },
157 	{ "keystrafeleft", type_hex, &keys[12], NULL },
158 	{ "keystraferight", type_hex, &keys[13], NULL },
159 	{ "key2dmode", type_hex, &keys[14], NULL },
160 	{ "keyviewcycle", type_hex, &keys[15], NULL },
161 	{ "key2dzoomin", type_hex, &keys[16], NULL },
162 	{ "key2dzoomout", type_hex, &keys[17], NULL },
163 	{ "keychat", type_hex, &keys[18], NULL },
164 	{ "keyconsole", type_hex, &keys[19], NULL },
165 	{ NULL, 0, NULL, NULL }
166 };
167 
loadsetup(const char * fn)168 int loadsetup(const char *fn)
169 {
170 	scriptfile *cfg;
171 	char *token;
172 	int item;
173 
174 	cfg = scriptfile_fromfile(fn);
175 	if (!cfg) {
176 		return -1;
177 	}
178 
179 	scriptfile_clearsymbols();
180 
181 	option[0] = 1;	// vesa all the way...
182 	option[1] = 1;	// sound all the way...
183 	option[4] = 0;	// no multiplayer
184 	option[5] = 0;
185 
186 	while (1) {
187 		token = scriptfile_gettoken(cfg);
188 		if (!token) break;	//EOF
189 
190 		for (item = 0; configspec[item].name; item++) {
191 			if (!Bstrcasecmp(token, configspec[item].name)) {
192 				// Seek past any = symbol.
193 				token = scriptfile_peektoken(cfg);
194 				if (!Bstrcasecmp("=", token)) {
195 					scriptfile_gettoken(cfg);
196 				}
197 
198 				switch (configspec[item].type) {
199 					case type_bool: {
200 						int value = 0;
201 						if (scriptfile_getnumber(cfg, &value)) break;
202 						*(int*)configspec[item].store = (value != 0);
203 						break;
204 					}
205 					case type_int: {
206 						int value = 0;
207 						if (scriptfile_getnumber(cfg, &value)) break;
208 						*(int*)configspec[item].store = value;
209 						break;
210 					}
211 					case type_hex: {
212 						int value = 0;
213 						if (scriptfile_gethex(cfg, &value)) break;
214 						*(int*)configspec[item].store = value;
215 						break;
216 					}
217 					case type_double: {
218 						double value = 0.0;
219 						if (scriptfile_getdouble(cfg, &value)) break;
220 						*(double*)configspec[item].store = value;
221 						break;
222 					}
223 					default: {
224 						buildputs("loadsetup: unhandled value type\n");
225 						break;
226 					}
227 				}
228 				break;
229 			}
230 		}
231 		if (!configspec[item].name) {
232 			buildprintf("loadsetup: error on line %d\n", scriptfile_getlinum(cfg, cfg->ltextptr));
233 			continue;
234 		}
235 	}
236 
237 #if USE_POLYMOST
238 	if (tmprenderer >= 0) {
239 		setrendermode(tmprenderer);
240 	}
241 #endif
242 	if (tmpbrightness >= 0) {
243 		brightness = min(max(tmpbrightness,0),15);
244 	}
245 	OSD_CaptureKey(keys[19]);
246 
247 	scriptfile_close(cfg);
248 	scriptfile_clearsymbols();
249 
250 	return 0;
251 }
252 
writesetup(const char * fn)253 int writesetup(const char *fn)
254 {
255 	BFILE *fp;
256 	int item;
257 
258 	fp = Bfopen(fn,"wt");
259 	if (!fp) return -1;
260 
261 	tmpbrightness = brightness;
262 #if USE_POLYMOST
263 	tmprenderer = getrendermode();
264 #endif
265 
266 	for (item = 0; configspec[item].name; item++) {
267 		if (configspec[item].doc) {
268 			if (item > 0) fputs("\n", fp);
269 			fputs(configspec[item].doc, fp);
270 		}
271 		fputs(configspec[item].name, fp);
272 		fputs(" = ", fp);
273 		switch (configspec[item].type) {
274 			case type_bool: {
275 				fprintf(fp, "%d\n", (*(int*)configspec[item].store != 0));
276 				break;
277 			}
278 			case type_int: {
279 				fprintf(fp, "%d\n", *(int*)configspec[item].store);
280 				break;
281 			}
282 			case type_hex: {
283 				fprintf(fp, "%X\n", *(int*)configspec[item].store);
284 				break;
285 			}
286 			case type_double: {
287 				fprintf(fp, "%g\n", *(double*)configspec[item].store);
288 				break;
289 			}
290 			default: {
291 				fputs("?\n", fp);
292 				break;
293 			}
294 		}
295 	}
296 
297 	Bfclose(fp);
298 
299 	return 0;
300 }
301