From bb0fc01e381169ce418db4db9ff70f479af9b118 Mon Sep 17 00:00:00 2001 From: Yamagi Date: Mon, 17 Feb 2020 17:56:54 +0100 Subject: [PATCH] Another try to fix the problem of spurious aborts of cinematics. Until this commit a cinematic was aborted as soon as any key were marked down when finishing the user command and sending it to the server. The whole logic to detect if a key is down is broken, for example `vid_restart` may leave keys marked down that are in fact up. And there's the possibility to inject fake key events from nearly everywhere. I'm not really sure but I suspect that even the server may be able to inject key events. Therefore untangle the cinematic abort code from the user command processing, it should depend only on real key strokes: 1. Introduce a new global variable `abort_cinamatic` and set it to `cls.realtime` as soon as a key down event is detected. The only exceptions are Escape and Shift, because opening the menu and toggeling the console should never abort a cinematic. 2. When starting a cinematic `abort_cinamatic` is set to INT_MAX, because it needs to be higher than the current `cls.realtime`. 3. When a cinematic is running, `cls.key_dest` is set to `key_game` (`key_menu` and `key_console` are ignored, keys send to the menu or the console should never abort a cinematic; `key_message` can / should never happen while a cinematic is running) and `abort_cinamatic` is less than `cls.realtime` the cinematic is aborted. `abort_cinamatic` less than `cls.realtime` is necessary because the client needs one frame to pop up the menu or toggle the console and set the `cls.key_dest` accordingly. `abort_cinamatic == cls.realtime - 1` is not possible because not every frame finishes a user command. This closes #502. --- src/client/cl_cin.c | 5 +++-- src/client/cl_input.c | 8 ++++---- src/client/cl_keyboard.c | 6 ++++++ src/client/header/client.h | 11 ++++++++--- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/client/cl_cin.c b/src/client/cl_cin.c index ba2bf5a4..ea907600 100644 --- a/src/client/cl_cin.c +++ b/src/client/cl_cin.c @@ -31,6 +31,7 @@ extern cvar_t *vid_renderer; cvar_t *cin_force43; +int abort_cinematic; typedef struct { @@ -321,8 +322,7 @@ Huff1Decompress(cblock_t in) int *hnodes, *hnodesbase; /* get decompressed count */ - count = in.data[0] + - (in.data[1] << 8) + (in.data[2] << 16) + (in.data[3] << 24); + count = in.data[0] + (in.data[1] << 8) + (in.data[2] << 16) + (in.data[3] << 24); input = in.data + 4; out_p = out.data = Z_Malloc(count); @@ -632,6 +632,7 @@ SCR_PlayCinematic(char *arg) char name[MAX_OSPATH], *dot; In_FlushQueue(); + abort_cinematic = INT_MAX; /* make sure background music is not playing */ OGG_Stop(); diff --git a/src/client/cl_input.c b/src/client/cl_input.c index 5cd5b439..32d0e613 100644 --- a/src/client/cl_input.c +++ b/src/client/cl_input.c @@ -776,8 +776,7 @@ CL_SendCmd(void) if (cls.state == ca_connected) { - if (cls.netchan.message.cursize || - (curtime - cls.netchan.last_sent > 1000)) + if (cls.netchan.message.cursize || (curtime - cls.netchan.last_sent > 1000)) { Netchan_Transmit(&cls.netchan, 0, buf.data); } @@ -796,8 +795,9 @@ CL_SendCmd(void) SZ_Init(&buf, data, sizeof(data)); - if (cmd->buttons && (cl.cinematictime > 0) && !cl.attractloop && - (cls.realtime - cl.cinematictime > 1000)) + if ((cls.realtime > abort_cinematic) && (cl.cinematictime > 0) && + !cl.attractloop && (cls.realtime - cl.cinematictime > 1000) && + (cls.key_dest == key_game)) { /* skip the rest of the cinematic */ SCR_FinishCinematic(); diff --git a/src/client/cl_keyboard.c b/src/client/cl_keyboard.c index c0d70434..e64aad1a 100644 --- a/src/client/cl_keyboard.c +++ b/src/client/cl_keyboard.c @@ -1118,6 +1118,12 @@ Key_Event(int key, qboolean down, qboolean special) /* Track if key is down */ keydown[key] = down; + /* Evil hack against spurious cinematic aborts. */ + if (down && (key != K_ESCAPE) && !keydown[K_SHIFT]) + { + abort_cinematic = cls.realtime; + } + /* Ignore most autorepeats */ if (down) { diff --git a/src/client/header/client.h b/src/client/header/client.h index b42abc02..4b2f59f6 100644 --- a/src/client/header/client.h +++ b/src/client/header/client.h @@ -261,11 +261,16 @@ typedef struct extern client_static_t cls; -/*Evil hack against too many power screen and power - shield impact sounds. For example if the player - fires his shotgun onto a Brain. */ +/* Evil hack against too many power screen and power + shield impact sounds. For example if the player + fires his shotgun onto a Brain. */ extern int num_power_sounds; +/* Even more evil hack against spurious cinematic + aborts caused by an unspeakable evil hack right + out of the deeps of hell... Aeh... KeyEvent(). */ +extern int abort_cinematic; + /* cvars */ extern cvar_t *gl1_stereo_separation; extern cvar_t *gl1_stereo_convergence;