shithub: qk1

Download patch

ref: 7d681dd51f2f119c8b05eb6d89221d897aed93e5
parent: 376e27387ce41157c13401981ecab105612c244e
author: qwx <>
date: Wed Sep 6 22:09:56 EDT 2017

fix bullshit input code

- update for (now old) kbdfs changes
- handle keyboard repeat when not ingame by just resending last key
  down (ignoring actual cons character)
- handle mouse wheel buttons ingame
- don't recenter mouse on every move; there is no justification for
  it, use a small grabrect instead
- ignore first mouse event after grab
- remove -nomouse, and -safe while we're at it
- rewrite retarded dedicated server input code; don't have setcvar
  sysfatal when a cvar hasn't been registered

--- a/common.c
+++ b/common.c
@@ -13,9 +13,6 @@
 static char     *largv[MAX_NUM_ARGVS + NUM_SAFE_ARGVS + 1];
 static char     *argvdummy = " ";
 
-static char     *safeargvs[NUM_SAFE_ARGVS] =
-	{"-stdvid", "-nolan", "-nosound", "-nojoy", "-nomouse", "-dibonly"};
-
 qboolean		msg_suppress_1 = 0;
 
 char	com_token[1024];
@@ -490,7 +487,6 @@
 */
 void COM_InitArgv (int argc, char **argv)
 {
-	qboolean        safe;
 	int             i, j, n;
 
 // reconstitute the command line for the cmdline externally visible cvar
@@ -513,25 +509,10 @@
 
 	com_cmdline[n] = 0;
 
-	safe = false;
-
 	for (com_argc=0 ; (com_argc<MAX_NUM_ARGVS) && (com_argc < argc) ;
 		 com_argc++)
 	{
 		largv[com_argc] = argv[com_argc];
-		if(strcmp("-safe", argv[com_argc]) == 0)
-			safe = true;
-	}
-
-	if (safe)
-	{
-	// force all the safe-mode switches. Note that we reserved extra space in
-	// case we need to add these, so we don't need an overflow check
-		for (i=0 ; i<NUM_SAFE_ARGVS ; i++)
-		{
-			largv[com_argc] = safeargvs[i];
-			com_argc++;
-		}
 	}
 
 	largv[com_argc] = argvdummy;
--- a/cvar.c
+++ b/cvar.c
@@ -148,8 +148,10 @@
 	cvar_t *cv;
 
 	cv = Cvar_FindVar(k);
-	if(cv == nil)
-		fatal("setcvar: no such cvar %s", k);
+	if(cv == nil){
+		fprint(2, "setcvar: no such cvar %s\n", k);
+		return;
+	}
 	n = strcmp(cv->string, k);
 	Z_Free(cv->string);
 	cv->string = Z_Malloc(strlen(v)+1);
--- a/fns.h
+++ b/fns.h
@@ -1,4 +1,4 @@
-char*	Sys_ConsoleInput(void);
+void	conscmd(void);
 void	Sys_SendKeyEvents(void);
 void	stepcd(void);
 void	stepsnd(vec3_t, vec3_t, vec3_t, vec3_t);
--- a/host.c
+++ b/host.c
@@ -422,27 +422,6 @@
 }
 
 /*
-===================
-Host_GetConsoleCommands
-
-Add them exactly as if they had been typed at the console
-===================
-*/
-void Host_GetConsoleCommands (void)
-{
-	char	*cmd;
-
-	while (1)
-	{
-		cmd = Sys_ConsoleInput ();
-		if (cmd == nil)
-			break;
-		Cbuf_AddText (cmd);
-	}
-}
-
-
-/*
 ==================
 Host_ServerFrame
 
@@ -524,7 +503,7 @@
 //-------------------
 
 // check for commands typed to the host
-	Host_GetConsoleCommands ();
+	conscmd();
 	
 	if (sv.active)
 		Host_ServerFrame ();
--- a/in.c
+++ b/in.c
@@ -1,5 +1,6 @@
 #include <u.h>
 #include <libc.h>
+#include <bio.h>
 #include <draw.h>
 #include <thread.h>
 #include <mouse.h>
@@ -11,45 +12,57 @@
 /* vid.c */
 extern int resized;
 extern Point center;
+extern Rectangle grabr;
 
 typedef struct Kev Kev;
 
 enum{
-	Nbuf = 24
+	Nbuf = 20
 };
-
 struct Kev{
 	int key;
 	int down;
 };
-static Channel *kchan;
+static Channel *inchan;
+static QLock mlck;
 
 static cvar_t m_windowed = {"m_windowed", "0", true};
 static cvar_t m_filter = {"m_filter", "0", true};
-static int mouseon;
+static int mouseon, fixms;
 static int oldmwin;
-static float mx;
-static float my;
-static float oldmx;
-static float oldmy;
-static int mb;
-static int oldmb;
-static int pfd[2];
+static float olddx, olddy;
+static int mΔx, mΔy, mb, oldmb;
 
+void
+conscmd(void)
+{
+	char *p;
 
-char *
-Sys_ConsoleInput(void)
+	if(cls.state != ca_dedicated)
+		return;
+	while(p = nbrecvp(inchan), p != nil){
+		Cbuf_AddText(p);
+		free(p);
+	}
+}
+
+static void
+cproc(void *)
 {
-	char buf[256];
+	char *s;
+	Biobuf *bf;
 
-	if(cls.state == ca_dedicated){
-		if(flen(pfd[1]) < 1)	/* only poll for input */
-			return nil;
-		if(read(pfd[1], buf, sizeof buf) < 0)
-			sysfatal("Sys_ConsoleInput:read: %r");
-		return buf;
+	if(bf = Bfdopen(0, OREAD), bf == nil)
+		sysfatal("Bfdopen: %r");
+	for(;;){
+		if(s = Brdstr(bf, '\n', 1), s == nil)
+			break;
+		if(sendp(inchan, s) < 0){
+			free(s);
+			break;
+		}
 	}
-	return nil;
+	Bterm(bf);
 }
 
 void
@@ -58,15 +71,14 @@
 	Kev ev;
 	int r;
 
-	if(kchan == nil)
+	if(cls.state == ca_dedicated)
 		return;
-
 	if(oldmwin != (int)m_windowed.value){
 		oldmwin = (int)m_windowed.value;
 		IN_Grabm(oldmwin);
 	}
 
-	while((r = nbrecv(kchan, &ev)) > 0)
+	while(r = nbrecv(inchan, &ev), r > 0)
 		Key_Event(ev.key, ev.down);
 	if(r < 0)
 		fprint(2, "Sys_SendKeyEvents: %r\n");
@@ -75,43 +87,53 @@
 void
 IN_Commands(void)
 {
-	int i, r;
+	int b, i, k, r;
 
-	if(!mouseon)
+	if(!mouseon || cls.state == ca_dedicated)
 		return;
-
-	for(i=0; i<3; i++){
-		r = mb & 1<<i;
+	qlock(&mlck);
+	b = mb;
+	qunlock(&mlck);
+	b = b & 0x19 | (b & 2) << 1 | (b & 4) >> 1;
+	for(i=0, k=K_MOUSE1; i<5; i++, k++){
+		if(i == 3)
+			k = K_MWHEELUP;
+		r = b & 1<<i;
 		if(r ^ oldmb & 1<<i)
-			Key_Event(K_MOUSE1+i, r);
+			Key_Event(k, r);
 	}
-	oldmb = mb;
+	oldmb = b & 7;
 }
 
 void
 IN_Move(usercmd_t *cmd)
 {
+	float dx, dy;
+
 	if(!mouseon)
 		return;
-   
+	qlock(&mlck);
+	dx = mΔx;
+	dy = mΔy;
+	mΔx = 0;
+	mΔy = 0;
+	qunlock(&mlck);
 	if(m_filter.value){
-		mx = (mx + oldmx) * 0.5;
-		my = (my + oldmy) * 0.5;
+		dx = (dx + olddx) * 0.5;
+		dy = (dy + olddy) * 0.5;
 	}
-	oldmx = mx;
-	oldmy = my;
-	mx *= sensitivity.value;
-	my *= sensitivity.value;
-   
+	olddx = dx;
+	olddy = dy;
+	dx *= sensitivity.value;
+	dy *= sensitivity.value;
 	if(in_strafe.state & 1 || lookstrafe.value && in_mlook.state & 1)
-		cmd->sidemove += m_side.value * mx;
+		cmd->sidemove += m_side.value * dx;
 	else
-		cl.viewangles[YAW] -= m_yaw.value * mx;
+		cl.viewangles[YAW] -= m_yaw.value * dx;
 	if(in_mlook.state & 1)
 		V_StopPitchDrift();
-   
 	if(in_mlook.state & 1 && ~in_strafe.state & 1){
-		cl.viewangles[PITCH] += m_pitch.value * my;
+		cl.viewangles[PITCH] += m_pitch.value * dy;
 		if(cl.viewangles[PITCH] > 80)
 			cl.viewangles[PITCH] = 80;
 		if(cl.viewangles[PITCH] < -70)
@@ -118,11 +140,10 @@
 			cl.viewangles[PITCH] = -70;
 	}else{
 		if(in_strafe.state & 1 && noclip_anglehack)
-			cmd->upmove -= m_forward.value * my;
+			cmd->upmove -= m_forward.value * dy;
 		else
-			cmd->forwardmove -= m_forward.value * my;
+			cmd->forwardmove -= m_forward.value * dy;
 	}
-	mx = my = 0.0;
 }
 
 static int
@@ -173,50 +194,57 @@
 kproc(void *)
 {
 	int n, k, fd;
-	char buf[128], kdown[128], *s;
+	char buf[256], kdown[128], *s, *p;
 	Rune r;
-	Kev ev;
+	Kev ev, evc;
 
-	threadsetgrp(1);
-
-	kdown[1] = kdown[0] = 0;
-	if((fd = open("/dev/kbd", OREAD)) < 0)
+	fd = open("/dev/kbd", OREAD);
+	if(fd < 0)
 		sysfatal("open /dev/kbd: %r");
-	while((n = read(fd, buf, sizeof buf)) > 0){
-		buf[n-1] = 0;
-		switch(*buf){
+	memset(buf, 0, sizeof buf);
+	evc.key = K_ENTER;
+	evc.down = true;
+	for(;;){
+		if(buf[0] != 0){
+			n = strlen(buf)+1;
+			memmove(buf, buf+n, sizeof(buf)-n);
+		}
+		if(buf[0] == 0){
+			if(n = read(fd, buf, sizeof(buf)-1), n <= 0)
+				break;
+			buf[n-1] = 0;
+			buf[n] = 0;
+		}
+		switch(buf[0]){
 		case 'c':
+			if(send(inchan, &evc) < 0)
+				threadexits(nil);
 		default:
 			continue;
 		case 'k':
+			ev.down = true;
 			s = buf+1;
-			while(*s){
-				s += chartorune(&r, s);
-				if(utfrune(kdown+1, r) == nil){
-					if(k = runetokey(r)){
-						ev.key = k;
-						ev.down = true;
-						if(nbsend(kchan, &ev) < 0)
-							fprint(2, "kproc: %r\n");
-					}
-				}
-			}
+			p = kdown+1;
 			break;
 		case 'K':
+			ev.down = false;
 			s = kdown+1;
-			while(*s){
-				s += chartorune(&r, s);
-				if(utfrune(buf+1, r) == nil){
-					if(k = runetokey(r)){
-						ev.key = k;
-						ev.down = false;
-						if(nbsend(kchan, &ev) < 0)
-							fprint(2, "kproc: %r\n");
-					}
-				}
-			}
+			p = buf+1;
 			break;
 		}
+		while(*s != 0){
+			s += chartorune(&r, s);
+			if(utfrune(p, r) == nil){
+				k = runetokey(r);
+				if(k == 0)
+					continue;
+				ev.key = k;
+				if(send(inchan, &ev) < 0)
+					threadexits(nil);
+				if(ev.down)
+					evc.key = k;
+			}
+		}
 		strcpy(kdown, buf);
 	}
 }
@@ -226,16 +254,15 @@
 {
 	int b, n, nerr, fd;
 	char buf[1+5*12];
-	float x, y;
+	Point p, o;
 
-	threadsetgrp(1);
-
-	if((fd = open("/dev/mouse", ORDWR)) < 0)
+	fd = open("/dev/mouse", ORDWR);
+	if(fd < 0)
 		sysfatal("open /dev/mouse: %r");
-
 	nerr = 0;
+	o = center;
 	for(;;){
-		if((n = read(fd, buf, sizeof buf)) != 1+4*12){
+		if(n = read(fd, buf, sizeof buf), n != 1+4*12){
 			if(n < 0 || ++nerr > 10)
 				break;
 			fprint(2, "mproc: bad count %d not 49: %r\n", n);
@@ -249,42 +276,29 @@
 		case 'm':
 			if(!mouseon)
 				break;
-
-			/* FIXME: this sucks: mouse movement is much smoother
-			 * and cursor rarely escapes the window, at the expense
-			 * of much more cpu and devmouse use */
-			x = atoi(buf+1+0*12) - center.x;
-			y = atoi(buf+1+1*12) - center.y;
+			if(fixms){
+				fixms = 0;
+				goto res;
+			}
+			p.x = atoi(buf+1+0*12);
+			p.y = atoi(buf+1+1*12);
 			b = atoi(buf+1+2*12);
-
-			mx += x;
-			my += y;
-			if(x != 0.0 ||  y != 0.0)
+			qlock(&mlck);
+			mΔx += p.x - o.x;
+			mΔy += p.y - o.y;
+			mb = b;
+			qunlock(&mlck);
+			if(!ptinrect(p, grabr)){
+		res:
 				fprint(fd, "m%d %d", center.x, center.y);
-
-			mb = b&1 | (b&2)<<1 | (b&4)>>1;
+				p = center;
+			}
+			o = p;
 			break;
 		}
 	}
 }
 
-static void
-iproc(void *)
-{
-	int n;
-	char s[256];
-
-	threadsetgrp(1);
-
-	for(;;){
-		if((n = read(0, s, sizeof s)) <= 0)
-			break;
-		s[n-1] = 0;
-		if((write(pfd[0], s, n)) != n)
-			break;
-	}
-}
-
 void
 IN_Grabm(int on)
 {
@@ -294,11 +308,13 @@
 	if(mouseon == on)
 		return;
 	if(mouseon = on && m_windowed.value){
-		if((fd = open("/dev/cursor", ORDWR|OCEXEC)) < 0){
+		fd = open("/dev/cursor", ORDWR|OCEXEC);
+		if(fd < 0){
 			fprint(2, "IN_Grabm:open: %r\n");
 			return;
 		}
 		write(fd, nocurs, sizeof nocurs);
+		fixms++;
 	}else if(fd >= 0){
 		close(fd);
 		fd = -1;
@@ -308,16 +324,8 @@
 void
 IN_Shutdown(void)
 {
+	chanfree(inchan);
 	IN_Grabm(0);
-	threadintgrp(1);
-	if(pfd[0] > 0)
-		close(pfd[0]);
-	if(pfd[1] > 0)
-		close(pfd[1]);
-	if(kchan != nil){
-		chanfree(kchan);
-		kchan = nil;
-	}
 }
 
 void
@@ -324,21 +332,18 @@
 IN_Init(void)
 {
 	if(cls.state == ca_dedicated){
-		if(pipe(pfd) < 0)
-			sysfatal("iproc:pipe: %r");
-		if(proccreate(iproc, nil, 8192) < 0)
+		if(inchan = chancreate(sizeof(void *), 2), inchan == nil)
+			sysfatal("chancreate: %r");
+		if(proccreate(cproc, nil, 8192) < 0)
 			sysfatal("proccreate iproc: %r");
 		return;
 	}
 	Cvar_RegisterVariable(&m_windowed);
 	Cvar_RegisterVariable(&m_filter);
-	if((kchan = chancreate(sizeof(Kev), Nbuf)) == nil)
-		sysfatal("chancreate kchan: %r");
+	if(inchan = chancreate(sizeof(Kev), Nbuf), inchan == nil)
+		sysfatal("chancreate: %r");
 	if(proccreate(kproc, nil, 8192) < 0)
 		sysfatal("proccreate kproc: %r");
-	if(COM_CheckParm("-nomouse"))
-		return;
 	if(proccreate(mproc, nil, 8192) < 0)
 		sysfatal("proccreate mproc: %r");
-	mx = my = 0.0;
 }
--- a/keys.c
+++ b/keys.c
@@ -568,12 +568,14 @@
 // update auto-repeat status
 	if (down)
 	{
-		key_repeats[key]++;
-		if (key != K_BACKSPACE && key != K_PAUSE && key_repeats[key] > 1)
-		{
-			return;	// ignore most autorepeats
-		}
-			
+		if(key != K_MWHEELUP && key != K_MWHEELDOWN)
+			key_repeats[key]++;
+		/* ignore cons event immediately following kbd down event */
+		if(key_repeats[key] == 2)
+			return;
+		if(key_repeats[key] > 2 && (key == K_ESCAPE || key == K_ENTER
+		|| key == '`' || key_dest == key_game))
+			return;
 		if (key >= 200 && !keybindings[key])
 			Con_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) );
 	}
--- a/vid.c
+++ b/vid.c
@@ -9,6 +9,7 @@
 int resized;
 int dumpwin;
 Point center;		/* of window */
+Rectangle grabr;
 int d_con_indirect;
 void (*vid_menudrawfn)(void);
 void (*vid_menukeyfn)(int key);
@@ -116,6 +117,7 @@
 	static int highhunk;
 	void *surfcache;
 	int hunkvbuf, scachesz;
+	Point p;
 
 	if(d_pzbuffer != nil){
 		D_FlushCaches();
@@ -140,6 +142,8 @@
 	vid.conheight = vid.height;
 
 	center = addpt(screen->r.min, Pt(vid.width/2, vid.height/2));
+	p = Pt(vid.width/4, vid.height/4);
+	grabr = Rpt(subpt(center, p), addpt(center, p));
 	freeimage(fbim);
 	free(framebuf);
 	fbim = allocimage(display, Rect(0,0,vid.width,vid.height), XRGB32, 0, 0);