shithub: wl3d

Download patch

ref: 581f80d934be37eece8c8dae06168d45f5fc2b54
parent: 8cdf6b06b9805fe39e72410549175e37415eb056
author: qwx <>
date: Fri Aug 11 16:26:03 EDT 2017

add configuration file

--- a/fns.h
+++ b/fns.h
@@ -5,6 +5,8 @@
 int	wrsav(int);
 int	ldsav(int);
 char*	demof(char*);
+void	wrconf(void);
+void	rdconf(void);
 u16int*	readmap(int);
 void	dat(char*);
 void	out(void);
--- a/fs.c
+++ b/fs.c
@@ -388,6 +388,8 @@
 	}
 };
 
+typedef struct Conf Conf;
+
 static u32int sodpal[] = {
 	0x003800, 0x002800,
 	0x203400, 0x202400,
@@ -459,6 +461,22 @@
 static u16int rlewtag;
 static u32int *mapofs, *mape;
 
+struct Conf{
+	char *s;
+	int *vp;
+	int isflag;
+};
+Conf confs[] = {
+	{"mouse", &grabon, 1},
+	{"msens", &msense},
+	{"vwsize", &vwsize},
+	{"autorun", &autorun, 1},
+	{"alsfx", &sfxon, 1},
+	{"pcmsfx", &pcmon, 1},
+	{"music", &muson, 1}
+};
+static int badconf;
+
 #define	GBIT16(p)	((p)[0]|((p)[1]<<8))
 
 static Biobuf *
@@ -1160,6 +1178,62 @@
 	Bterm(bf);
 	ext = e;
 	return p;
+}
+
+void
+wrconf(void)
+{
+	int fd;
+	Biobuf *bf;
+	Conf *c;
+
+	if(badconf)
+		return;
+	fd = create("wlconf", OWRITE, 0666);
+	bf = Bfdopen(fd, OWRITE);
+	if(fd < 0 || bf == nil)
+		sysfatal("wrconf: %r");
+	for(c=confs; c<confs+nelem(confs); c++)
+		Bprint(bf, "%s %d\n", c->s, *c->vp);
+	Bterm(bf);
+}
+
+void
+rdconf(void)
+{
+	int n, ln;
+	char *s, *p, *fld[2];
+	Biobuf *bf;
+	Conf *c;
+
+	bf = Bopen("wlconf", OREAD);
+	if(bf == nil)
+		return;
+	for(ln=1, s=nil;; ln++){
+		free(s);
+		s = Brdstr(bf, '\n', 1);
+		if(s == nil)
+			break;
+		n = getfields(s, fld, nelem(fld), 1, " ");
+		if(n != nelem(fld))
+			goto err;
+		for(c=confs; c<confs+nelem(confs); c++)
+			if(strcmp(fld[0], c->s) == 0){
+				n = strtol(fld[1], &p, 0);
+				if(p == fld[1])
+					goto err;
+				*c->vp = c->isflag ? n != 0 : n;
+				break;
+			}
+		if(c == confs + nelem(confs)){
+err:
+			fprint(2, "rdconf: invalid entry, line %d\n", ln);
+			badconf++;
+			break;
+		}
+	}
+	free(s);
+	Bterm(bf);
 }
 
 void
--- a/hub.c
+++ b/hub.c
@@ -206,21 +206,21 @@
 	{"I am Death incarnate!", DIreg, ql+Ldifc4}
 },
 isnd[] = {
-	{"None", SEL(DIreg), ql+Lsndtog},
+	{"None", SEL(DIreg)},
 	{"PC Speaker"},
-	{"AdLib/Sound Blaster", DIreg, nil, 1},
+	{"AdLib/Sound Blaster", DIreg},
 	{nil},
 	{nil},
-	{"None", DIreg, ql+Lsndtog},
+	{"None", DIreg},
 	{"Disney Sound Source"},
-	{"Sound Blaster", DIreg, nil, 1},
+	{"Sound Blaster", DIreg},
 	{nil},
 	{nil},
-	{"None", DIreg, ql+Lsndtog},
-	{"AdLib/Sound Blaster", DIreg, nil, 1}
+	{"None", DIreg},
+	{"AdLib/Sound Blaster", DIreg}
 },
 iin[] = {
-	{"Mouse Enabled", SEL(DIreg), ql+Lintog, 1},
+	{"Mouse Enabled", SEL(DIreg), ql+Lintog},
 	{"Autorun Enabled", DIreg, ql+Lintog},
 	{"Mouse Sensitivity", DIreg, ql+Lfsens}
 },
@@ -361,11 +361,11 @@
 			return;
 		switch(mp->p - i){
 		case 0: iswp(i, i+2); stopsfx(); sfxon = 0; break;
-		case 2: iswp(i+2, i); sfxon++; sfx(Sshoot); break;
+		case 2: iswp(i+2, i); sfxon = 1; sfx(Sshoot); break;
 		case 5: iswp(i+5, i+7); pcmon = 0; break;
-		case 7: iswp(i+7, i+5); pcmon++; break;
+		case 7: iswp(i+7, i+5); pcmon = 1; break;
 		case 10: iswp(i+10, i+11); stopmus(); muson = 0; sfx(Sshoot); break;
-		case 11: iswp(i+11, i+10); muson++; mus(Mmenu); break;
+		case 11: iswp(i+11, i+10); muson = 1; mus(Mmenu); break;
 		}
 		break;
 	case LMin:
@@ -1542,6 +1542,7 @@
 static void
 exit(void)
 {
+	wrconf();
 	threadexitsall(nil);
 }
 
@@ -1719,14 +1720,19 @@
 }
 
 static void
-cfg(void)
+conf(void)
 {
+	static int *vs[] = {&sfxon, &pcmon, &muson},
+		is[] = {2, 0, 7, 5, 11, 10};
+	int *ip, **vp;
+	int n, m;
+
 	muson = sfxon = pcmon = 1;
-	grabon++;
+	grabon = 1;
 	autorun = 0;
 	msense = 5;
 	vwsize = 15;
-	/* fs.c: load config file and read values */
+	rdconf();
 	if(msense < 0)
 		msense = 0;
 	else if(msense > 9)
@@ -1736,6 +1742,14 @@
 	else if(vwsize > 19)
 		vwsize = 19;
 	setvw();
+	iin[0].a = grabon;
+	iin[1].a = autorun;
+	for(vp=vs, ip=is; vp<vs+nelem(vs); vp++){
+		n = *ip++;
+		m = *ip++;
+		isnd[m].a = !(isnd[n].a = **vp);
+		isnd[isnd[m].a ? n : m].q = ql+Lsndtog;
+	}
 }
 
 static void
@@ -1886,7 +1900,7 @@
 init(char *f, int m, int d)
 {
 	srand(time(nil));
-	cfg();
+	conf();
 	initseqs();
 	inctl();
 	demd = dems;
--- a/man/1/wl3d
+++ b/man/1/wl3d
@@ -162,7 +162,36 @@
 (see
 .IR audio (3))
 is inaccessible, audio is ignored.
-.PD
+.SS Configuration file
+Configuration strings are loaded from a file
+.L wlconf
+in the current working directory.
+It is overwritten when
+.I wl3d
+exits,
+excepting when it was not parsed successfully on program load.
+Its format is a series of key-value pairs, one per line,
+separated by a space character.
+.L vwsize
+and
+.L msens
+control the size of the draw area and mouse sensitivity,
+and their values are bounded respectively to 0-9 and 4-19.
+.LR mouse ,
+.LR autorun ,
+.LR alsfx ,
+.LR pcmsfx
+and
+.LR music
+are toggles for enabling mouse use,
+moving at full speed at all times,
+.SM Adlib
+sound effects, digital sound effects, and music.
+A value of
+.L 0
+disables the setting, and
+.L 1
+enables it.
 .SS Differences
 Most of
 .I wl3d
@@ -186,9 +215,9 @@
 Menus are implemented differently, and some have been altered in functionality.
 Debug mode has been removed, and cheats work differently.
 .PP
-Game keys are no longer set in the options menu, but rather in the configuration file.
+Game keys are no longer set in the options menu.
 A single configuration file is used for all game versions.
-Savegames and config files are incompatible in format.
+Savegames and configuration files are incompatible in format.
 .PP
 The texture and sprite scaling implementation does not attempt to save memory and avoids quantization at close range.
 .SH FILES