From 5dfe9918d0b477661344be88e32026d3ad7381df Mon Sep 17 00:00:00 2001
From: Christoph Oelckers <coelckers@users.noreply.github.com>
Date: Sat, 13 Jun 2020 20:31:57 +0200
Subject: [PATCH] - moved some event related code to 'common'.

---
 src/CMakeLists.txt                            |   2 +
 src/common/2d/v_2ddrawer.cpp                  |   1 -
 src/common/console/c_bind.cpp                 |   2 +-
 src/common/engine/d_event.cpp                 | 198 ++++++++++++++++++
 src/common/engine/d_eventbase.h               |  76 +++++++
 src/common/engine/d_gui.h                     | 115 ++++++++++
 src/common/engine/m_joy.cpp                   |   2 +-
 src/common/platform/posix/cocoa/i_input.mm    |   2 +-
 .../platform/posix/cocoa/i_joystick.cpp       |   2 +-
 src/common/platform/posix/sdl/i_input.cpp     |   2 +-
 src/common/platform/win32/i_dijoy.cpp         |   2 +-
 src/common/platform/win32/i_input.cpp         |   2 +-
 src/common/platform/win32/i_keyboard.cpp      |   2 +-
 src/common/platform/win32/i_main.cpp          |   1 +
 src/common/platform/win32/i_mouse.cpp         |   2 +-
 src/common/platform/win32/i_rawps2.cpp        |   2 +-
 src/common/platform/win32/i_xinput.cpp        |   2 +-
 src/common/rendering/v_video.cpp              |   2 +-
 src/common/scripting/core/dictionary.cpp      |   2 +-
 src/d_event.h                                 |  37 +---
 src/d_main.cpp                                |  70 -------
 src/events.cpp                                |  83 --------
 src/events.h                                  |  34 ---
 src/g_game.cpp                                |   4 +
 24 files changed, 410 insertions(+), 237 deletions(-)
 create mode 100644 src/common/engine/d_event.cpp
 create mode 100644 src/common/engine/d_eventbase.h
 create mode 100644 src/common/engine/d_gui.h

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e0e39bb43..2cd9bb662 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1105,6 +1105,7 @@ set (PCH_SOURCES
 	common/filesystem/file_directory.cpp
 	common/filesystem/resourcefile.cpp
 	common/engine/cycler.cpp
+	common/engine/d_event.cpp
 	common/engine/stats.cpp
 	common/engine/sc_man.cpp
 	common/engine/palettecontainer.cpp
@@ -1283,6 +1284,7 @@ include_directories( .
 	rendering/2d
 	r_data
 	sound
+	menu
 	sound/backend
 	xlat
 	utility
diff --git a/src/common/2d/v_2ddrawer.cpp b/src/common/2d/v_2ddrawer.cpp
index a7f6b2d7b..564c122c3 100644
--- a/src/common/2d/v_2ddrawer.cpp
+++ b/src/common/2d/v_2ddrawer.cpp
@@ -651,7 +651,6 @@ void F2DDrawer::AddPoly(FGameTexture* img, FVector4* vt, size_t vtcount, unsigne
 
 	dg.mTexture = img;
 	dg.mTranslationId = translation;
-	dg.mColor1 = color;
 	dg.mVertCount = (int)vtcount;
 	dg.mVertIndex = (int)mVertices.Reserve(vtcount);
 	dg.mRenderStyle = LegacyRenderStyles[STYLE_Translucent];
diff --git a/src/common/console/c_bind.cpp b/src/common/console/c_bind.cpp
index 5e82f5bd0..c5a540645 100644
--- a/src/common/console/c_bind.cpp
+++ b/src/common/console/c_bind.cpp
@@ -47,7 +47,7 @@
 #include "sc_man.h"
 #include "c_cvars.h"
 
-#include "d_event.h"
+#include "d_eventbase.h"
 
 extern int chatmodeon;
 
diff --git a/src/common/engine/d_event.cpp b/src/common/engine/d_event.cpp
new file mode 100644
index 000000000..c58a98df1
--- /dev/null
+++ b/src/common/engine/d_event.cpp
@@ -0,0 +1,198 @@
+/*
+** c_dispatch.cpp
+** Functions for executing console commands and aliases
+**
+**---------------------------------------------------------------------------
+** Copyright 1998-2016 Randy Heit
+** Copyright 2003-2019 Christoph Oelckers
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+**
+** 1. Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in the
+**    documentation and/or other materials provided with the distribution.
+** 3. The name of the author may not be used to endorse or promote products
+**    derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**---------------------------------------------------------------------------
+**
+*/ 
+
+#include "c_bind.h"
+#include "d_eventbase.h"
+#include "c_console.h"
+#include "d_gui.h"
+#include "menu.h"
+#include "utf8.h"
+#include "m_joy.h"
+#include "vm.h"
+
+bool G_Responder(event_t* ev);
+
+int eventhead;
+int eventtail;
+event_t events[MAXEVENTS];
+
+//==========================================================================
+//
+// D_ProcessEvents
+//
+// Send all the events of the given timestamp down the responder chain.
+// Events are asynchronous inputs generally generated by the game user.
+// Events can be discarded if no responder claims them
+//
+//==========================================================================
+
+void D_ProcessEvents (void)
+{
+	event_t *ev;
+	while (eventtail != eventhead)
+	{
+		ev = &events[eventtail];
+		eventtail = (eventtail + 1) & (MAXEVENTS - 1);
+		if (ev->type == EV_None)
+			continue;
+		if (ev->type == EV_DeviceChange)
+			UpdateJoystickMenu(I_UpdateDeviceList());
+		if (C_Responder (ev))
+			continue;				// console ate the event
+		if (M_Responder (ev))
+			continue;				// menu ate the event
+		G_Responder (ev);
+	}
+}
+
+//==========================================================================
+//
+// D_RemoveNextCharEvent
+//
+// Removes the next EV_GUI_Char event in the input queue. Used by the menu,
+// since it (generally) consumes EV_GUI_KeyDown events and not EV_GUI_Char
+// events, and it needs to ensure that there is no left over input when it's
+// done. If there are multiple EV_GUI_KeyDowns before the EV_GUI_Char, then
+// there are dead chars involved, so those should be removed, too. We do
+// this by changing the message type to EV_None rather than by actually
+// removing the event from the queue.
+// 
+//==========================================================================
+
+void D_RemoveNextCharEvent()
+{
+	assert(events[eventtail].type == EV_GUI_Event && events[eventtail].subtype == EV_GUI_KeyDown);
+	for (int evnum = eventtail; evnum != eventhead; evnum = (evnum+1) & (MAXEVENTS-1))
+	{
+		event_t *ev = &events[evnum];
+		if (ev->type != EV_GUI_Event)
+			break;
+		if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_Char)
+		{
+			ev->type = EV_None;
+			if (ev->subtype == EV_GUI_Char)
+				break;
+		}
+		else
+		{
+			break;
+		}
+	}
+}
+ 
+
+FInputEvent::FInputEvent(const event_t *ev)
+{
+	Type = (EGenericEvent)ev->type;
+	// we don't want the modders to remember what weird fields mean what for what events.
+	KeyScan = 0;
+	KeyChar = 0;
+	MouseX = 0;
+	MouseY = 0;
+	switch (Type)
+	{
+	case EV_None:
+		break;
+	case EV_KeyDown:
+	case EV_KeyUp:
+		KeyScan = ev->data1;
+		KeyChar = ev->data2;
+		KeyString = FString(char(ev->data1));
+		break;
+	case EV_Mouse:
+		MouseX = ev->x;
+		MouseY = ev->y;
+		break;
+	default:
+		break; // EV_DeviceChange = wat?
+	}
+}
+
+FUiEvent::FUiEvent(const event_t *ev)
+{
+	Type = (EGUIEvent)ev->subtype;
+	KeyChar = 0;
+	IsShift = false;
+	IsAlt = false;
+	IsCtrl = false;
+	MouseX = 0;
+	MouseY = 0;
+	// we don't want the modders to remember what weird fields mean what for what events.
+	switch (ev->subtype)
+	{
+	case EV_GUI_None:
+		break;
+	case EV_GUI_KeyDown:
+	case EV_GUI_KeyRepeat:
+	case EV_GUI_KeyUp:
+		KeyChar = ev->data1;
+		KeyString = FString(char(ev->data1));
+		IsShift = !!(ev->data3 & GKM_SHIFT);
+		IsAlt = !!(ev->data3 & GKM_ALT);
+		IsCtrl = !!(ev->data3 & GKM_CTRL);
+		break;
+	case EV_GUI_Char:
+		KeyChar = ev->data1;
+		KeyString = MakeUTF8(ev->data1);
+		IsAlt = !!ev->data2; // only true for Win32, not sure about SDL
+		break;
+	default: // mouse event
+			 // note: SDL input doesn't seem to provide these at all
+			 //Printf("Mouse data: %d, %d, %d, %d\n", ev->x, ev->y, ev->data1, ev->data2);
+		MouseX = ev->data1;
+		MouseY = ev->data2;
+		IsShift = !!(ev->data3 & GKM_SHIFT);
+		IsAlt = !!(ev->data3 & GKM_ALT);
+		IsCtrl = !!(ev->data3 & GKM_CTRL);
+		break;
+	}
+}
+
+DEFINE_FIELD_X(UiEvent, FUiEvent, Type);
+DEFINE_FIELD_X(UiEvent, FUiEvent, KeyString);
+DEFINE_FIELD_X(UiEvent, FUiEvent, KeyChar);
+DEFINE_FIELD_X(UiEvent, FUiEvent, MouseX);
+DEFINE_FIELD_X(UiEvent, FUiEvent, MouseY);
+DEFINE_FIELD_X(UiEvent, FUiEvent, IsShift);
+DEFINE_FIELD_X(UiEvent, FUiEvent, IsAlt);
+DEFINE_FIELD_X(UiEvent, FUiEvent, IsCtrl);
+
+DEFINE_FIELD_X(InputEvent, FInputEvent, Type);
+DEFINE_FIELD_X(InputEvent, FInputEvent, KeyScan);
+DEFINE_FIELD_X(InputEvent, FInputEvent, KeyString);
+DEFINE_FIELD_X(InputEvent, FInputEvent, KeyChar);
+DEFINE_FIELD_X(InputEvent, FInputEvent, MouseX);
+DEFINE_FIELD_X(InputEvent, FInputEvent, MouseY);
+
diff --git a/src/common/engine/d_eventbase.h b/src/common/engine/d_eventbase.h
new file mode 100644
index 000000000..9e06acde3
--- /dev/null
+++ b/src/common/engine/d_eventbase.h
@@ -0,0 +1,76 @@
+#pragma once
+#include <stdint.h>
+#include "d_gui.h"
+
+// Input event types.
+enum EGenericEvent
+{
+	EV_None,
+	EV_KeyDown,		// data1: scan code, data2: Qwerty ASCII code
+	EV_KeyUp,		// same
+	EV_Mouse,		// x, y: mouse movement deltas
+	EV_GUI_Event,	// subtype specifies actual event
+	EV_DeviceChange,// a device has been connected or removed
+};
+
+// Event structure.
+struct event_t
+{
+	uint8_t		type;
+	uint8_t		subtype;
+	int16_t 	data1;		// keys / mouse/joystick buttons
+	int16_t		data2;
+	int16_t		data3;
+	int 		x;			// mouse/joystick x move
+	int 		y;			// mouse/joystick y move
+};
+
+
+
+// Called by IO functions when input is detected.
+void D_PostEvent (const event_t* ev);
+void D_RemoveNextCharEvent();
+void D_ProcessEvents(void);
+
+enum
+{
+	MAXEVENTS = 128
+};
+
+extern	event_t 		events[MAXEVENTS];
+extern int eventhead;
+extern int eventtail;
+
+struct FUiEvent
+{
+	// this essentially translates event_t UI events to ZScript.
+	EGUIEvent Type;
+	// for keys/chars/whatever
+	FString KeyString;
+	int KeyChar;
+	// for mouse
+	int MouseX;
+	int MouseY;
+	// global (?)
+	bool IsShift;
+	bool IsCtrl;
+	bool IsAlt;
+
+	FUiEvent(const event_t *ev);
+};
+
+struct FInputEvent
+{
+	// this translates regular event_t events to ZScript (not UI, UI events are sent via DUiEvent and only if requested!)
+	EGenericEvent Type = EV_None;
+	// for keys
+	int KeyScan;
+	FString KeyString;
+	int KeyChar;
+	// for mouse
+	int MouseX;
+	int MouseY;
+
+	FInputEvent(const event_t *ev);
+};
+
diff --git a/src/common/engine/d_gui.h b/src/common/engine/d_gui.h
new file mode 100644
index 000000000..774f928ac
--- /dev/null
+++ b/src/common/engine/d_gui.h
@@ -0,0 +1,115 @@
+/*
+** d_gui.h
+**
+**---------------------------------------------------------------------------
+** Copyright 1998-2006 Randy Heit
+** All rights reserved.
+**
+** Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+**
+** 1. Redistributions of source code must retain the above copyright
+**    notice, this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright
+**    notice, this list of conditions and the following disclaimer in the
+**    documentation and/or other materials provided with the distribution.
+** 3. The name of the author may not be used to endorse or promote products
+**    derived from this software without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**---------------------------------------------------------------------------
+**
+** So when do I get a real UT-like windowing system?
+*/
+
+#ifndef __D_GUI_H__
+#define __D_GUI_H__
+
+// For a GUIEvent, x and y specify absolute location of mouse pointer
+enum EGUIEvent
+{
+	EV_GUI_None,
+	EV_GUI_KeyDown,			// data1: unshifted ASCII, data2: shifted ASCII, data3: modifiers
+	EV_GUI_KeyRepeat,		// same
+	EV_GUI_KeyUp,			// same
+	EV_GUI_Char,			// data1: translated character (for user text input), data2: alt down?
+	EV_GUI_FirstMouseEvent,
+		EV_GUI_MouseMove,
+		EV_GUI_LButtonDown,
+		EV_GUI_LButtonUp,
+		EV_GUI_LButtonDblClick,
+		EV_GUI_MButtonDown,
+		EV_GUI_MButtonUp,
+		EV_GUI_MButtonDblClick,
+		EV_GUI_RButtonDown,
+		EV_GUI_RButtonUp,
+		EV_GUI_RButtonDblClick,
+		EV_GUI_WheelUp,			// data3: shift/ctrl/alt
+		EV_GUI_WheelDown,		// "
+		EV_GUI_WheelRight,		// "
+		EV_GUI_WheelLeft,		// "
+		EV_GUI_BackButtonDown,
+		EV_GUI_BackButtonUp,
+		EV_GUI_FwdButtonDown,
+		EV_GUI_FwdButtonUp,
+	EV_GUI_LastMouseEvent,
+};
+
+enum GUIKeyModifiers
+{
+	GKM_SHIFT	= 1,
+	GKM_CTRL	= 2,
+	GKM_ALT		= 4,
+	GKM_META	= 8,
+	GKM_LBUTTON = 16
+};
+
+// Special codes for some GUI keys, including a few real ASCII codes.
+enum ESpecialGUIKeys
+{
+	GK_PGDN		= 1,
+	GK_PGUP		= 2,
+	GK_HOME		= 3,
+	GK_END		= 4,
+	GK_LEFT		= 5,
+	GK_RIGHT	= 6,
+	GK_ALERT	= 7,		// ASCII bell
+	GK_BACKSPACE= 8,		// ASCII
+	GK_TAB		= 9,		// ASCII
+	GK_LINEFEED	= 10,		// ASCII
+	GK_DOWN		= 10,
+	GK_VTAB		= 11,		// ASCII
+	GK_UP		= 11,
+	GK_FORMFEED	= 12,		// ASCII
+	GK_RETURN	= 13,		// ASCII
+	GK_F1		= 14,
+	GK_F2		= 15,
+	GK_F3		= 16,
+	GK_F4		= 17,
+	GK_F5		= 18,
+	GK_F6		= 19,
+	GK_F7		= 20,
+	GK_F8		= 21,
+	GK_F9		= 22,
+	GK_F10		= 23,
+	GK_F11		= 24,
+	GK_F12		= 25,
+	GK_DEL		= 26,
+	GK_ESCAPE	= 27,		// ASCII
+	GK_FREE1	= 28,
+	GK_FREE2	= 29,
+	GK_BACK		= 30,		// browser back key
+	GK_CESCAPE	= 31		// color escape
+};
+
+#endif //__D_GUI_H__
diff --git a/src/common/engine/m_joy.cpp b/src/common/engine/m_joy.cpp
index c20b406c7..578287ad5 100644
--- a/src/common/engine/m_joy.cpp
+++ b/src/common/engine/m_joy.cpp
@@ -36,7 +36,7 @@
 #include "vectors.h"
 #include "m_joy.h"
 #include "gameconfigfile.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "cmdlib.h"
 #include "printf.h"
 
diff --git a/src/common/platform/posix/cocoa/i_input.mm b/src/common/platform/posix/cocoa/i_input.mm
index dad875fba..3b562bcb8 100644
--- a/src/common/platform/posix/cocoa/i_input.mm
+++ b/src/common/platform/posix/cocoa/i_input.mm
@@ -38,7 +38,7 @@
 #include "c_console.h"
 #include "c_cvars.h"
 #include "c_dispatch.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "c_buttons.h"
 #include "d_gui.h"
 #include "dikeys.h"
diff --git a/src/common/platform/posix/cocoa/i_joystick.cpp b/src/common/platform/posix/cocoa/i_joystick.cpp
index d7d7587ac..6f0e22c8b 100644
--- a/src/common/platform/posix/cocoa/i_joystick.cpp
+++ b/src/common/platform/posix/cocoa/i_joystick.cpp
@@ -35,7 +35,7 @@
 #include <IOKit/IOMessage.h>
 #include <IOKit/hid/IOHIDLib.h>
 
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "i_system.h"
 #include "m_argv.h"
 #include "m_joy.h"
diff --git a/src/common/platform/posix/sdl/i_input.cpp b/src/common/platform/posix/sdl/i_input.cpp
index 164b0b228..6b34e6d64 100644
--- a/src/common/platform/posix/sdl/i_input.cpp
+++ b/src/common/platform/posix/sdl/i_input.cpp
@@ -34,7 +34,7 @@
 #include "m_argv.h"
 #include "v_video.h"
 
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "d_gui.h"
 #include "c_buttons.h"
 #include "c_console.h"
diff --git a/src/common/platform/win32/i_dijoy.cpp b/src/common/platform/win32/i_dijoy.cpp
index 0d471ab18..eb016fdd4 100644
--- a/src/common/platform/win32/i_dijoy.cpp
+++ b/src/common/platform/win32/i_dijoy.cpp
@@ -44,7 +44,7 @@
 #include <malloc.h>
 
 #include "i_input.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "templates.h"
 #include "gameconfigfile.h"
 #include "cmdlib.h"
diff --git a/src/common/platform/win32/i_input.cpp b/src/common/platform/win32/i_input.cpp
index 2a67766bd..8e9af9fa6 100644
--- a/src/common/platform/win32/i_input.cpp
+++ b/src/common/platform/win32/i_input.cpp
@@ -77,7 +77,7 @@
 #include "s_soundinternal.h"
 #include "gameconfigfile.h"
 #include "hardware.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "v_text.h"
 #include "version.h"
 #include "engineerrors.h"
diff --git a/src/common/platform/win32/i_keyboard.cpp b/src/common/platform/win32/i_keyboard.cpp
index 9567809f5..7fdb83e3e 100644
--- a/src/common/platform/win32/i_keyboard.cpp
+++ b/src/common/platform/win32/i_keyboard.cpp
@@ -39,7 +39,7 @@
 #include <dinput.h>
 
 #include "i_input.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 
 
 // MACROS ------------------------------------------------------------------
diff --git a/src/common/platform/win32/i_main.cpp b/src/common/platform/win32/i_main.cpp
index 0eaceba72..e92867ba2 100644
--- a/src/common/platform/win32/i_main.cpp
+++ b/src/common/platform/win32/i_main.cpp
@@ -572,6 +572,7 @@ void I_SetWndProc()
 		SetWindowLongPtr (Window, GWLP_USERDATA, 1);
 		SetWindowLongPtr (Window, GWLP_WNDPROC, (WLONG_PTR)WndProc);
 		ShowWindow (ConWindow, SW_HIDE);
+		ShowWindow(ProgressBar, SW_HIDE);
 		ConWindowHidden = true;
 		ShowWindow (GameTitleWindow, SW_HIDE);
 		I_InitInput (Window);
diff --git a/src/common/platform/win32/i_mouse.cpp b/src/common/platform/win32/i_mouse.cpp
index a3aaec674..329da45d7 100644
--- a/src/common/platform/win32/i_mouse.cpp
+++ b/src/common/platform/win32/i_mouse.cpp
@@ -39,7 +39,7 @@
 #include <dinput.h>
 
 #include "i_input.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "d_gui.h"
 #include "hardware.h"
 #include "menu/menu.h"
diff --git a/src/common/platform/win32/i_rawps2.cpp b/src/common/platform/win32/i_rawps2.cpp
index a6b31970f..2a7547f3e 100644
--- a/src/common/platform/win32/i_rawps2.cpp
+++ b/src/common/platform/win32/i_rawps2.cpp
@@ -37,7 +37,7 @@
 #include <windows.h>
 
 #include "i_input.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "templates.h"
 #include "gameconfigfile.h"
 #include "m_argv.h"
diff --git a/src/common/platform/win32/i_xinput.cpp b/src/common/platform/win32/i_xinput.cpp
index e473d8bd2..7085de82f 100644
--- a/src/common/platform/win32/i_xinput.cpp
+++ b/src/common/platform/win32/i_xinput.cpp
@@ -39,7 +39,7 @@
 #include <limits.h>
 
 #include "i_input.h"
-#include "d_event.h"
+#include "d_eventbase.h"
 #include "templates.h"
 #include "gameconfigfile.h"
 #include "m_argv.h"
diff --git a/src/common/rendering/v_video.cpp b/src/common/rendering/v_video.cpp
index ce4dab80a..2f11b86e3 100644
--- a/src/common/rendering/v_video.cpp
+++ b/src/common/rendering/v_video.cpp
@@ -78,7 +78,7 @@ CUSTOM_CVAR(Int, vid_maxfps, 200, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
 	{
 		self = GameTicRate;
 	}
-	else if (vid_maxfps > 1000)
+	else if (self > 1000)
 	{
 		self = 1000;
 	}
diff --git a/src/common/scripting/core/dictionary.cpp b/src/common/scripting/core/dictionary.cpp
index 753ac66fe..6d2b1d092 100644
--- a/src/common/scripting/core/dictionary.cpp
+++ b/src/common/scripting/core/dictionary.cpp
@@ -29,7 +29,7 @@ void Dictionary::Serialize(FSerializer &arc)
 {
 	Super::Serialize(arc);
 
-	constexpr char key[] { "dictionary" };
+	static const char key[] = "dictionary";
 
 	if (arc.isWriting())
 	{
diff --git a/src/d_event.h b/src/d_event.h
index 82fd978ed..7188f6ccc 100644
--- a/src/d_event.h
+++ b/src/d_event.h
@@ -26,35 +26,9 @@
 
 #include "basics.h"
 #include <functional>
+#include "d_eventbase.h"
 
 
-//
-// Event handling.
-//
-
-// Input event types.
-enum EGenericEvent
-{
-	EV_None,
-	EV_KeyDown,		// data1: scan code, data2: Qwerty ASCII code
-	EV_KeyUp,		// same
-	EV_Mouse,		// x, y: mouse movement deltas
-	EV_GUI_Event,	// subtype specifies actual event
-	EV_DeviceChange,// a device has been connected or removed
-};
-
-// Event structure.
-struct event_t
-{
-	uint8_t		type;
-	uint8_t		subtype;
-	int16_t 		data1;		// keys / mouse/joystick buttons
-	int16_t		data2;
-	int16_t		data3;
-	int 		x;			// mouse/joystick x move
-	int 		y;			// mouse/joystick y move
-};
-
  
 enum gameaction_t : int
 {
@@ -119,18 +93,9 @@ typedef enum
 } buttoncode_t;
 
 // Called by IO functions when input is detected.
-void D_PostEvent (const event_t* ev);
-void D_RemoveNextCharEvent();
 void D_Render(std::function<void()> action, bool interpolate);
 
 
-//
-// GLOBAL VARIABLES
-//
-#define MAXEVENTS		128
-
-extern	event_t 		events[MAXEVENTS];
-
 extern	gameaction_t	gameaction;
 
 
diff --git a/src/d_main.cpp b/src/d_main.cpp
index 4ec7536a3..3ff6d9f6b 100644
--- a/src/d_main.cpp
+++ b/src/d_main.cpp
@@ -301,9 +301,6 @@ bool autostart;
 bool advancedemo;
 FILE *debugfile;
 FILE *hashfile;
-event_t events[MAXEVENTS];
-int eventhead;
-int eventtail;
 gamestate_t wipegamestate = GS_DEMOSCREEN;	// can be -1 to force a wipe
 bool PageBlank;
 FGameTexture *Advisory;
@@ -444,38 +441,6 @@ CCMD(togglehud)
 	D_ToggleHud();
 }
 
-//==========================================================================
-//
-// D_ProcessEvents
-//
-// Send all the events of the given timestamp down the responder chain.
-// Events are asynchronous inputs generally generated by the game user.
-// Events can be discarded if no responder claims them
-//
-//==========================================================================
-
-void D_ProcessEvents (void)
-{
-	event_t *ev;
-		
-	for (; eventtail != eventhead ; eventtail = (eventtail+1)&(MAXEVENTS-1))
-	{
-		ev = &events[eventtail];
-		if (ev->type == EV_None)
-			continue;
-		if (ev->type == EV_DeviceChange)
-			UpdateJoystickMenu(I_UpdateDeviceList());
-		if (C_Responder (ev))
-			continue;				// console ate the event
-		if (M_Responder (ev))
-			continue;				// menu ate the event
-		// check events
-		if (ev->type != EV_Mouse && primaryLevel->localEventManager->Responder(ev)) // [ZZ] ZScript ate the event // update 07.03.17: mouse events are handled directly
-			continue;
-		G_Responder (ev);
-	}
-}
-
 //==========================================================================
 //
 // D_PostEvent
@@ -518,41 +483,6 @@ void D_PostEvent (const event_t *ev)
 	eventhead = (eventhead+1)&(MAXEVENTS-1);
 }
 
-//==========================================================================
-//
-// D_RemoveNextCharEvent
-//
-// Removes the next EV_GUI_Char event in the input queue. Used by the menu,
-// since it (generally) consumes EV_GUI_KeyDown events and not EV_GUI_Char
-// events, and it needs to ensure that there is no left over input when it's
-// done. If there are multiple EV_GUI_KeyDowns before the EV_GUI_Char, then
-// there are dead chars involved, so those should be removed, too. We do
-// this by changing the message type to EV_None rather than by actually
-// removing the event from the queue.
-// 
-//==========================================================================
-
-void D_RemoveNextCharEvent()
-{
-	assert(events[eventtail].type == EV_GUI_Event && events[eventtail].subtype == EV_GUI_KeyDown);
-	for (int evnum = eventtail; evnum != eventhead; evnum = (evnum+1) & (MAXEVENTS-1))
-	{
-		event_t *ev = &events[evnum];
-		if (ev->type != EV_GUI_Event)
-			break;
-		if (ev->subtype == EV_GUI_KeyDown || ev->subtype == EV_GUI_Char)
-		{
-			ev->type = EV_None;
-			if (ev->subtype == EV_GUI_Char)
-				break;
-		}
-		else
-		{
-			break;
-		}
-	}
-}
-
 //==========================================================================
 //
 // Render wrapper.
diff --git a/src/events.cpp b/src/events.cpp
index eafefb09e..08b713068 100755
--- a/src/events.cpp
+++ b/src/events.cpp
@@ -630,22 +630,6 @@ DEFINE_FIELD_X(WorldEvent, FWorldEvent, NewDamage);
 DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, PlayerNumber);
 DEFINE_FIELD_X(PlayerEvent, FPlayerEvent, IsReturn);
 
-DEFINE_FIELD_X(UiEvent, FUiEvent, Type);
-DEFINE_FIELD_X(UiEvent, FUiEvent, KeyString);
-DEFINE_FIELD_X(UiEvent, FUiEvent, KeyChar);
-DEFINE_FIELD_X(UiEvent, FUiEvent, MouseX);
-DEFINE_FIELD_X(UiEvent, FUiEvent, MouseY);
-DEFINE_FIELD_X(UiEvent, FUiEvent, IsShift);
-DEFINE_FIELD_X(UiEvent, FUiEvent, IsAlt);
-DEFINE_FIELD_X(UiEvent, FUiEvent, IsCtrl);
-
-DEFINE_FIELD_X(InputEvent, FInputEvent, Type);
-DEFINE_FIELD_X(InputEvent, FInputEvent, KeyScan);
-DEFINE_FIELD_X(InputEvent, FInputEvent, KeyString);
-DEFINE_FIELD_X(InputEvent, FInputEvent, KeyChar);
-DEFINE_FIELD_X(InputEvent, FInputEvent, MouseX);
-DEFINE_FIELD_X(InputEvent, FInputEvent, MouseY);
-
 DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, Player)
 DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, Name)
 DEFINE_FIELD_X(ConsoleEvent, FConsoleEvent, Args)
@@ -1050,46 +1034,6 @@ void DStaticEventHandler::PlayerDisconnected(int num)
 	}
 }
 
-FUiEvent::FUiEvent(const event_t *ev)
-{
-	Type = (EGUIEvent)ev->subtype;
-	KeyChar = 0;
-	IsShift = false;
-	IsAlt = false;
-	IsCtrl = false;
-	MouseX = 0;
-	MouseY = 0;
-	// we don't want the modders to remember what weird fields mean what for what events.
-	switch (ev->subtype)
-	{
-	case EV_GUI_None:
-		break;
-	case EV_GUI_KeyDown:
-	case EV_GUI_KeyRepeat:
-	case EV_GUI_KeyUp:
-		KeyChar = ev->data1;
-		KeyString = FString(char(ev->data1));
-		IsShift = !!(ev->data3 & GKM_SHIFT);
-		IsAlt = !!(ev->data3 & GKM_ALT);
-		IsCtrl = !!(ev->data3 & GKM_CTRL);
-		break;
-	case EV_GUI_Char:
-		KeyChar = ev->data1;
-		KeyString = MakeUTF8(ev->data1);
-		IsAlt = !!ev->data2; // only true for Win32, not sure about SDL
-		break;
-	default: // mouse event
-			 // note: SDL input doesn't seem to provide these at all
-			 //Printf("Mouse data: %d, %d, %d, %d\n", ev->x, ev->y, ev->data1, ev->data2);
-		MouseX = ev->data1;
-		MouseY = ev->data2;
-		IsShift = !!(ev->data3 & GKM_SHIFT);
-		IsAlt = !!(ev->data3 & GKM_ALT);
-		IsCtrl = !!(ev->data3 & GKM_CTRL);
-		break;
-	}
-}
-
 bool DStaticEventHandler::UiProcess(const event_t* ev)
 {
 	IFVIRTUAL(DStaticEventHandler, UiProcess)
@@ -1108,33 +1052,6 @@ bool DStaticEventHandler::UiProcess(const event_t* ev)
 	return false;
 }
 
-FInputEvent::FInputEvent(const event_t *ev)
-{
-	Type = (EGenericEvent)ev->type;
-	// we don't want the modders to remember what weird fields mean what for what events.
-	KeyScan = 0;
-	KeyChar = 0;
-	MouseX = 0;
-	MouseY = 0;
-	switch (Type)
-	{
-	case EV_None:
-		break;
-	case EV_KeyDown:
-	case EV_KeyUp:
-		KeyScan = ev->data1;
-		KeyChar = ev->data2;
-		KeyString = FString(char(ev->data1));
-		break;
-	case EV_Mouse:
-		MouseX = ev->x;
-		MouseY = ev->y;
-		break;
-	default:
-		break; // EV_DeviceChange = wat?
-	}
-}
-
 bool DStaticEventHandler::InputProcess(const event_t* ev)
 {
 	IFVIRTUAL(DStaticEventHandler, InputProcess)
diff --git a/src/events.h b/src/events.h
index c0ecb047b..6690b16cd 100755
--- a/src/events.h
+++ b/src/events.h
@@ -3,7 +3,6 @@
 #include "dobject.h"
 #include "serializer.h"
 #include "d_event.h"
-#include "d_gui.h"
 #include "sbar.h"
 
 class DStaticEventHandler;
@@ -175,39 +174,6 @@ struct FPlayerEvent
 	bool IsReturn;
 };
 
-struct FUiEvent
-{
-	// this essentially translates event_t UI events to ZScript.
-	EGUIEvent Type;
-	// for keys/chars/whatever
-	FString KeyString;
-	int KeyChar;
-	// for mouse
-	int MouseX;
-	int MouseY;
-	// global (?)
-	bool IsShift;
-	bool IsCtrl;
-	bool IsAlt;
-
-	FUiEvent(const event_t *ev);
-};
-
-struct FInputEvent
-{
-	// this translates regular event_t events to ZScript (not UI, UI events are sent via DUiEvent and only if requested!)
-	EGenericEvent Type = EV_None;
-	// for keys
-	int KeyScan;
-	FString KeyString;
-	int KeyChar;
-	// for mouse
-	int MouseX;
-	int MouseY;
-
-	FInputEvent(const event_t *ev);
-};
-
 struct FConsoleEvent 
 {
 	// player that activated this event. note that it's always -1 for non-playsim events (i.e. these not called with netevent)
diff --git a/src/g_game.cpp b/src/g_game.cpp
index 95f37f069..aa15419c5 100644
--- a/src/g_game.cpp
+++ b/src/g_game.cpp
@@ -965,6 +965,10 @@ CCMD (spycancel)
 //
 bool G_Responder (event_t *ev)
 {
+	// check events
+	if (ev->type != EV_Mouse && primaryLevel->localEventManager->Responder(ev)) // [ZZ] ZScript ate the event // update 07.03.17: mouse events are handled directly
+		return true;
+	
 	// any other key pops up menu if in demos
 	// [RH] But only if the key isn't bound to a "special" command
 	if (gameaction == ga_nothing &&