ref: 3ebd884ebb70433445614272d81f29ea66b90c75
parent: c80ce20775776c2a02b08e84566ef3aa887bcf62
author: qwx <qwx@sciops.net>
date: Tue Jul 20 09:29:33 EDT 2021
keys: implement key autorepeat - in: just don't send first useless cons message on key down - keys: cleaner autorepeat implementation, don't bother counting anything - like for qw, set key_dest correctly for when we are on the console and disconnected; don't autorepeat ingame; ignore special keys - fix a few mouse grabbing instances - remove "model key press hack", unused
--- a/cl_cin.c
+++ b/cl_cin.c
@@ -576,6 +576,7 @@
cl.cinematictime = 1;
SCR_EndLoadingPlaque ();
cls.state = ca_active;
+ CL_SetGameInput(key_game);
if (!cin.pic)
{
Com_Printf ("%s not found.\n", name);
@@ -602,6 +603,7 @@
SCR_EndLoadingPlaque ();
cls.state = ca_active;
+ CL_SetGameInput(key_game);
FS_Read (&width, 4, cl.cinematic_file);
FS_Read (&height, 4, cl.cinematic_file);
--- a/cl_ents.c
+++ b/cl_ents.c
@@ -739,6 +739,7 @@
if (cls.state != ca_active)
{
cls.state = ca_active;
+ CL_SetGameInput(key_game);
cl.force_refdef = true;
cl.predicted_origin[0] = cl.frame.playerstate.pmove.origin[0]*0.125;
cl.predicted_origin[1] = cl.frame.playerstate.pmove.origin[1]*0.125;
--- a/cl_main.c
+++ b/cl_main.c
@@ -76,7 +76,24 @@
//======================================================================
+void
+CL_SetGameInput(k)
+{
+ switch(cls.key_dest = k){
+ case key_game:
+ IN_Grabm(1);
+ if(Cvar_VariableValue("maxclients") == 1 && Com_ServerState())
+ Cvar_Set("paused", "0");
+ break;
+ default:
+ IN_Grabm(0);
+ if(Cvar_VariableValue("maxclients") == 1 && Com_ServerState())
+ Cvar_Set("paused", "1");
+ break;
+ }
+}
+
/*
====================
CL_WriteDemoMessage
@@ -580,7 +597,7 @@
VectorClear (cl.refdef.blend);
re.CinematicSetPalette(NULL);
- M_ForceMenuOff ();
+ M_ForceMenuOff(false);
cls.connect_time = 0;
--- a/console.c
+++ b/console.c
@@ -65,23 +65,7 @@
Key_ClearTyping ();
Con_ClearNotify ();
-
- if (cls.key_dest == key_console)
- {
- M_ForceMenuOff ();
- Cvar_Set ("paused", "0");
- IN_Grabm (1);
- }
- else
- {
- M_ForceMenuOff ();
- cls.key_dest = key_console;
-
- if (Cvar_VariableValue ("maxclients") == 1
- && Com_ServerState ())
- Cvar_Set ("paused", "1");
- IN_Grabm (0);
- }
+ M_ForceMenuOff(cls.key_dest == key_console && cls.state == ca_active);
}
/*
@@ -96,10 +80,7 @@
if (cls.key_dest == key_console)
{
if (cls.state == ca_active)
- {
- M_ForceMenuOff ();
- cls.key_dest = key_game;
- }
+ M_ForceMenuOff(true);
}
else
cls.key_dest = key_console;
--- a/dat.h
+++ b/dat.h
@@ -2457,7 +2457,6 @@
K_PAUSE = 255
};
extern char *keybindings[256];
-extern int key_repeats[256];
extern int anykeydown;
extern char chat_buffer[];
extern int chat_bufferlen;
--- a/fns.h
+++ b/fns.h
@@ -288,7 +288,7 @@
void M_Keydown(int);
void M_Draw(void);
void M_Menu_Main_f(void);
-void M_ForceMenuOff(void);
+void M_ForceMenuOff(qboolean);
void M_AddToServerList(netadr_t, char *);
void CL_ParseInventory(void);
void CL_KeyInventory(int);
@@ -296,6 +296,7 @@
void CL_PredictMovement(void);
qboolean CL_CheckOrDownloadFile(char *);
void CL_AddNetgraph(void);
+void CL_SetGameInput(int);
void SV_Init(void);
void SV_Shutdown(char *, qboolean);
@@ -584,7 +585,7 @@
void IN_Activate(qboolean);
void IN_Grabm(int);
-void Key_Event(int, qboolean, unsigned);
+void Key_Event(int, qboolean, qboolean, unsigned);
void Key_Init(void);
void Key_WriteBindings(FILE *);
void Key_SetBinding(int, char *);
--- a/in.c
+++ b/in.c
@@ -35,6 +35,7 @@
struct Kev{
int key;
int down;
+ int isrep;
};
enum{
Nbuf = 64
@@ -100,9 +101,9 @@
for(i = 0; i < 3; i++){
b = 1<<i;
if(btn & b && ~oldb & b)
- Key_Event(K_MOUSE1+i, true, msec);
+ Key_Event(K_MOUSE1+i, true, false, msec);
else if(~btn & b && oldb & b)
- Key_Event(K_MOUSE1+i, false, msec);
+ Key_Event(K_MOUSE1+i, false, false, msec);
}
oldb = btn & 7;
/* mwheelup and mwheeldn buttons are never held down */
@@ -109,8 +110,8 @@
for(i = 3; i < 5; i++){
b = 1<<i;
if(btn & b){
- Key_Event(K_MOUSE1+i, true, msec);
- Key_Event(K_MOUSE1+i, false, msec);
+ Key_Event(K_MOUSE1+i, true, false, msec);
+ Key_Event(K_MOUSE1+i, false, false, msec);
}
}
}
@@ -127,7 +128,7 @@
IN_Grabm(m_windowed->value);
}
while((r = nbrecv(kchan, &ev)) > 0)
- Key_Event(ev.key, ev.down, Sys_Milliseconds());
+ Key_Event(ev.key, ev.down, ev.isrep, Sys_Milliseconds());
if(r < 0)
sysfatal("KBD_Update:nbrecv: %r\n");
while((r = nbrecv(mchan, &m)) > 0){
@@ -253,14 +254,20 @@
static void
kproc(void *)
{
- int n, k, fd;
- char buf[128], kdown[128], *s;
+ int n, k, fd, rep;
+ char buf[128], kdown[128], *s, *p;
Rune r;
- Kev ev;
+ Kev ev, evc;
if((fd = open("/dev/kbd", OREAD)) < 0)
sysfatal("kproc: %r");
- kdown[0] = kdown[1] = buf[0] = 0;
+ memset(buf, 0, sizeof buf);
+ memset(kdown, 0, sizeof kdown);
+ evc.key = K_ENTER;
+ evc.down = true;
+ evc.isrep = true;
+ ev.isrep = false;
+ rep = 0;
for(;;){
if(buf[0] != 0){
n = strlen(buf)+1;
@@ -267,48 +274,44 @@
memmove(buf, buf+n, sizeof(buf)-n);
}
if(buf[0] == 0){
- n = read(fd, buf, sizeof(buf)-1);
- if(n <= 0)
+ if((n = read(fd, buf, sizeof(buf)-1)) <= 0)
break;
buf[n-1] = 0;
buf[n] = 0;
}
- switch(*buf){
+ switch(buf[0]){
case 'c':
+ if(rep++ > 0 && send(kchan, &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(send(kchan, &ev) < 0)
- goto end;
- }
- }
- }
+ 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(send(kchan, &ev) < 0)
- goto end;
- }
+ p = buf+1;
+ break;
+ }
+ while(*s != 0){
+ s += chartorune(&r, s);
+ if(utfrune(p, r) == nil){
+ if((k = runetokey(r)) == 0)
+ continue;
+ ev.key = k;
+ if(send(kchan, &ev) < 0)
+ threadexits(nil);
+ if(ev.down){
+ evc.key = k;
+ rep = 0;
}
}
- break;
}
strcpy(kdown, buf);
}
-end:;
}
static void
--- a/keys.c
+++ b/keys.c
@@ -20,12 +20,10 @@
int edit_line=0;
int history_line=0;
-int key_waiting;
char *keybindings[256];
qboolean consolekeys[256]; // if true, can't be rebound while in console
qboolean menubound[256]; // if true, can't be rebound while in menu
int keyshift[256]; // key to map to if shift held down in console
-int key_repeats[256]; // if > 1, it is autorepeating
qboolean keydown[256];
typedef struct
@@ -722,39 +720,39 @@
Should NOT be called during an interrupt!
===================
*/
-void Key_Event (int key, qboolean down, unsigned time)
+void Key_Event (int key, qboolean down, qboolean isrep, unsigned time)
{
char *kb;
char cmd[1024];
- // hack for modal presses
- if (key_waiting == -1)
- {
- if (down)
- key_waiting = key;
- return;
- }
-
// update auto-repeat status
if (down)
{
- key_repeats[key]++;
- if (key != K_BACKSPACE
- && key != K_PAUSE
- && key != K_PGUP
- && key != K_KP_PGUP
- && key != K_PGDN
- && key != K_KP_PGDN
- && key_repeats[key] > 1)
- return; // ignore most autorepeats
-
+ if(isrep){
+ /* no autorepeat for anything ingame */
+ if(cls.key_dest == key_game)
+ return;
+ /* ignore hardcoded specially-handled keys */
+ switch(key){
+ case K_ESCAPE:
+ case '`':
+ case '~':
+ case K_ENTER:
+ case K_KP_ENTER:
+ case K_INS: /* paste clipboard data */
+ case K_KP_INS:
+ case K_END: /* jump to end */
+ case K_KP_END:
+ case K_TAB: /* autocomplete */
+ return;
+ }
+ /* cons still sending repeats but key state has been cleared */
+ if(!keydown[key])
+ return;
+ }
if (key >= 200 && !keybindings[key])
Com_Printf ("%s is unbound, hit F4 to set.\n", Key_KeynumToString (key) );
}
- else
- {
- key_repeats[key] = 0;
- }
if (key == K_SHIFT)
shift_down = down;
@@ -803,15 +801,11 @@
// track if any key is down for BUTTON_ANY
keydown[key] = down;
- if (down)
- {
- if (key_repeats[key] == 1)
- anykeydown++;
- }
- else
- {
+ if(down && !isrep)
+ anykeydown++;
+ else{
anykeydown--;
- if (anykeydown < 0)
+ if(anykeydown < 0)
anykeydown = 0;
}
@@ -899,30 +893,12 @@
{
int i;
- anykeydown = false;
+ anykeydown = 0;
for (i=0 ; i<256 ; i++)
{
- if ( keydown[i] || key_repeats[i] )
- Key_Event( i, false, 0 );
- keydown[i] = 0;
- key_repeats[i] = 0;
+ if(keydown[i])
+ Key_Event(i, false, false, 0);
+ keydown[i] = false;
}
}
-
-
-/*
-===================
-Key_GetKey
-===================
-*/
-int Key_GetKey (void)
-{
- key_waiting = -1;
-
- while (key_waiting == -1)
- Sys_SendKeyEvents ();
-
- return key_waiting;
-}
-
--- a/menu.c
+++ b/menu.c
@@ -65,9 +65,7 @@
{
int i;
- if (Cvar_VariableValue ("maxclients") == 1
- && Com_ServerState ())
- Cvar_Set ("paused", "1");
+ CL_SetGameInput(key_menu);
// if this menu is already present, drop back to that level
// to avoid stacking menus by hotkeys
@@ -91,19 +89,16 @@
m_keyfunc = key;
m_entersound = true;
-
- cls.key_dest = key_menu;
}
-void M_ForceMenuOff (void)
+void
+M_ForceMenuOff(qboolean set)
{
m_drawfunc = 0;
m_keyfunc = 0;
- cls.key_dest = key_game;
m_menudepth = 0;
- Key_ClearStates ();
- Cvar_Set ("paused", "0");
- IN_Grabm (1);
+ Key_ClearStates();
+ CL_SetGameInput(set ? key_game : key_console);
}
void M_PopMenu (void)
@@ -117,7 +112,7 @@
m_keyfunc = m_layers[m_menudepth].key;
if (!m_menudepth)
- M_ForceMenuOff ();
+ M_ForceMenuOff(cls.state == ca_active);
}
@@ -469,7 +464,6 @@
void M_Menu_Main_f (void)
{
- IN_Grabm (0);
M_PushMenu (M_Main_Draw, M_Main_Key);
}
@@ -1140,8 +1134,7 @@
Key_ClearTyping ();
Con_ClearNotify ();
- M_ForceMenuOff ();
- cls.key_dest = key_console;
+ M_ForceMenuOff(false);
}
void Options_MenuInit( void )
@@ -1824,7 +1817,7 @@
{
// disable updates and start the cinematic going
cl.servercount = -1;
- M_ForceMenuOff ();
+ M_ForceMenuOff(true);
Cvar_SetValue( "deathmatch", 0 );
Cvar_SetValue( "coop", 0 );
@@ -1831,7 +1824,6 @@
Cvar_SetValue( "gamerules", 0 ); //PGM
Cbuf_AddText ("loading ; killserver ; wait ; newgame\n");
- cls.key_dest = key_game;
}
static void EasyGameFunc( void * )
@@ -2003,7 +1995,7 @@
if ( m_savevalid[ a->generic.localdata[0] ] )
Cbuf_AddText (va("load save%i\n", a->generic.localdata[0] ) );
- M_ForceMenuOff ();
+ M_ForceMenuOff(true);
}
void LoadGame_MenuInit( void )
@@ -2074,7 +2066,7 @@
menuaction_t *a = ( menuaction_t * ) self;
Cbuf_AddText (va("save save%i\n", a->generic.localdata[0] ));
- M_ForceMenuOff ();
+ M_ForceMenuOff(true);
}
void SaveGame_MenuDraw( void )
@@ -2192,7 +2184,7 @@
Com_sprintf (buffer, sizeof(buffer), "connect %s\n", NET_AdrToString (local_server_netadr[index]));
Cbuf_AddText (buffer);
- M_ForceMenuOff ();
+ M_ForceMenuOff(true);
}
void AddressBookFunc( void * )
@@ -2444,8 +2436,7 @@
{
Cbuf_AddText (va("map %s\n", startmap));
}
-
- M_ForceMenuOff ();
+ M_ForceMenuOff(true);
}
void StartServer_MenuInit( void )
--- a/vmenu.c
+++ b/vmenu.c
@@ -36,7 +36,7 @@
{
Cvar_SetValue("vid_gamma", 0.8 - (gammaslide.curvalue/10.0 - 0.5) + 0.5);
Cvar_SetValue("vid_fullscreen", fullscrbox.curvalue);
- M_ForceMenuOff();
+ M_ForceMenuOff(cls.state == ca_active);
}
void