5369: Refactor engine input in preparation for joystick support r=def- a=Robyt3

Almost done porting joystick support 🥁

## Checklist

- [X] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: Robert Müller <robytemueller@gmail.com>
This commit is contained in:
bors[bot] 2022-06-06 21:12:45 +00:00 committed by GitHub
commit b8d3deef33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 107 additions and 99 deletions

View file

@ -1,24 +1,24 @@
# pylint: skip-file
# generate keys.h file
f = file("src/engine/keys.h", "w")
f = open("src/engine/keys.h", "w")
keynames = []
for i in range(0, 512):
keynames += ["&%d"%i]
print >>f, "#ifndef ENGINE_KEYS_H"
print >>f, "#define ENGINE_KEYS_H"
print("#ifndef ENGINE_KEYS_H", file=f)
print("#define ENGINE_KEYS_H", file=f)
# KEY_EXECUTE already exists on windows platforms
print >>f, "#if defined(CONF_FAMILY_WINDOWS)"
print >>f, " #undef KEY_EXECUTE"
print >>f, "#endif"
print("#if defined(CONF_FAMILY_WINDOWS)", file=f)
print(" #undef KEY_EXECUTE", file=f)
print("#endif", file=f)
print >>f, '/* AUTO GENERATED! DO NOT EDIT MANUALLY! */'
print >>f, "enum"
print >>f, "{"
print('/* AUTO GENERATED! DO NOT EDIT MANUALLY! */', file=f)
print("enum", file=f)
print("{", file=f)
print >>f, "\tKEY_FIRST = 0,"
print("\tKEY_FIRST = 0,", file=f)
highestid = 0
for line in open("scripts/SDL_scancode.h"):
@ -28,48 +28,49 @@ for line in open("scripts/SDL_scancode.h"):
value = int(l[1].split(",")[0].strip())
if key[0:2] == "/*":
continue
print >>f, "\t%s = %d,"%(key, value)
print("\t%s = %d,"%(key, value), file=f)
keynames[value] = key.replace("KEY_", "").lower()
if value > highestid:
highestid =value
highestid = value
print >>f, "\tKEY_MOUSE_1 = %d,"%(highestid+1); keynames[highestid+1] = "mouse1"
print >>f, "\tKEY_MOUSE_2 = %d,"%(highestid+2); keynames[highestid+2] = "mouse2"
print >>f, "\tKEY_MOUSE_3 = %d,"%(highestid+3); keynames[highestid+3] = "mouse3"
print >>f, "\tKEY_MOUSE_4 = %d,"%(highestid+4); keynames[highestid+4] = "mouse4"
print >>f, "\tKEY_MOUSE_5 = %d,"%(highestid+5); keynames[highestid+5] = "mouse5"
print >>f, "\tKEY_MOUSE_6 = %d,"%(highestid+6); keynames[highestid+6] = "mouse6"
print >>f, "\tKEY_MOUSE_7 = %d,"%(highestid+7); keynames[highestid+7] = "mouse7"
print >>f, "\tKEY_MOUSE_8 = %d,"%(highestid+8); keynames[highestid+8] = "mouse8"
print >>f, "\tKEY_MOUSE_9 = %d,"%(highestid+9); keynames[highestid+9] = "mouse9"
print >>f, "\tKEY_MOUSE_WHEEL_UP = %d,"%(highestid+10); keynames[highestid+10] = "mousewheelup"
print >>f, "\tKEY_MOUSE_WHEEL_DOWN = %d,"%(highestid+11); keynames[highestid+11] = "mousewheeldown"
print >>f, "\tKEY_MOUSE_WHEEL_LEFT = %d,"%(highestid+12); keynames[highestid+12] = "mousewheelleft"
print >>f, "\tKEY_MOUSE_WHEEL_RIGHT = %d,"%(highestid+13); keynames[highestid+13] = "mousewheelright"
print >>f, "\tKEY_LAST = 512,"
highestid += 1
print("\tKEY_MOUSE_1 = %d,"%(highestid), file=f); keynames[highestid] = "mouse1"; highestid += 1
print("\tKEY_MOUSE_2 = %d,"%(highestid), file=f); keynames[highestid] = "mouse2"; highestid += 1
print("\tKEY_MOUSE_3 = %d,"%(highestid), file=f); keynames[highestid] = "mouse3"; highestid += 1
print("\tKEY_MOUSE_4 = %d,"%(highestid), file=f); keynames[highestid] = "mouse4"; highestid += 1
print("\tKEY_MOUSE_5 = %d,"%(highestid), file=f); keynames[highestid] = "mouse5"; highestid += 1
print("\tKEY_MOUSE_6 = %d,"%(highestid), file=f); keynames[highestid] = "mouse6"; highestid += 1
print("\tKEY_MOUSE_7 = %d,"%(highestid), file=f); keynames[highestid] = "mouse7"; highestid += 1
print("\tKEY_MOUSE_8 = %d,"%(highestid), file=f); keynames[highestid] = "mouse8"; highestid += 1
print("\tKEY_MOUSE_9 = %d,"%(highestid), file=f); keynames[highestid] = "mouse9"; highestid += 1
print("\tKEY_MOUSE_WHEEL_UP = %d,"%(highestid), file=f); keynames[highestid] = "mousewheelup"; highestid += 1
print("\tKEY_MOUSE_WHEEL_DOWN = %d,"%(highestid), file=f); keynames[highestid] = "mousewheeldown"; highestid += 1
print("\tKEY_MOUSE_WHEEL_LEFT = %d,"%(highestid), file=f); keynames[highestid] = "mousewheelleft"; highestid += 1
print("\tKEY_MOUSE_WHEEL_RIGHT = %d,"%(highestid), file=f); keynames[highestid] = "mousewheelright"; highestid += 1
print("\tKEY_LAST = 512,", file=f)
print >>f, "};"
print >>f, ""
print >>f, "#endif"
print("};", file=f)
print("", file=f)
print("#endif", file=f)
# generate keynames.c file
f = file("src/engine/client/keynames.h", "w")
print >>f, '/* AUTO GENERATED! DO NOT EDIT MANUALLY! */'
print >>f, ''
print >>f, '#ifndef KEYS_INCLUDE'
print >>f, '#error do not include this header!'
print >>f, '#endif'
print >>f, ''
print >>f, "#include <string.h>"
print >>f, ""
print >>f, "const char g_aaKeyStrings[512][20] ="
print >>f, "{"
f = open("src/engine/client/keynames.h", "w")
print('/* AUTO GENERATED! DO NOT EDIT MANUALLY! */', file=f)
print('', file=f)
print('#ifndef KEYS_INCLUDE', file=f)
print('#error do not include this header!', file=f)
print('#endif', file=f)
print('', file=f)
print("#include <string.h>", file=f)
print("", file=f)
print("const char g_aaKeyStrings[512][20] = // NOLINT(misc-definitions-in-headers)", file=f)
print("{", file=f)
for n in keynames:
print >>f, '\t"%s",'%n
print('\t"%s",'%n, file=f)
print >>f, "};"
print >>f, ""
print("};", file=f)
print("", file=f)
f.close()

View file

@ -55,9 +55,11 @@ CInput::CInput()
m_NumTextInputInstances = 0;
m_EditingTextLen = -1;
m_aEditingText[0] = 0;
}
m_LastX = 0;
m_LastY = 0;
CInput::~CInput()
{
SDL_free(m_pClipboardText);
}
void CInput::Init()
@ -69,20 +71,22 @@ void CInput::Init()
MouseModeRelative();
}
void CInput::MouseRelative(float *x, float *y)
bool CInput::MouseRelative(float *pX, float *pY)
{
if(!m_MouseFocus || !m_InputGrabbed)
return;
return false;
int nx = 0, ny = 0;
float Sens = g_Config.m_InpMousesens / 100.0f;
#if defined(CONF_PLATFORM_ANDROID) // No relative mouse on Android
static int s_LastX = 0;
static int s_LastY = 0;
SDL_GetMouseState(&nx, &ny);
int XTmp = nx - m_LastX;
int YTmp = ny - m_LastY;
m_LastX = nx;
m_LastY = ny;
int XTmp = nx - s_LastX;
int YTmp = ny - s_LastY;
s_LastX = nx;
s_LastY = ny;
nx = XTmp;
ny = YTmp;
Sens = 1;
@ -90,8 +94,9 @@ void CInput::MouseRelative(float *x, float *y)
SDL_GetRelativeMouseState(&nx, &ny);
#endif
*x = nx * Sens;
*y = ny * Sens;
*pX = nx * Sens;
*pY = ny * Sens;
return *pX != 0.0f || *pY != 0.0f;
}
void CInput::MouseModeAbsolute()
@ -112,19 +117,15 @@ void CInput::MouseModeRelative()
SDL_GetRelativeMouseState(0x0, 0x0);
}
void CInput::NativeMousePos(int *x, int *y) const
void CInput::NativeMousePos(int *pX, int *pY) const
{
int nx = 0, ny = 0;
SDL_GetMouseState(&nx, &ny);
*x = nx;
*y = ny;
SDL_GetMouseState(pX, pY);
}
bool CInput::NativeMousePressed(int index)
bool CInput::NativeMousePressed(int Index)
{
int i = SDL_GetMouseState(NULL, NULL);
return (i & SDL_BUTTON(index)) != 0;
return (i & SDL_BUTTON(Index)) != 0;
}
bool CInput::MouseDoubleClick()
@ -144,9 +145,9 @@ const char *CInput::GetClipboardText()
return m_pClipboardText;
}
void CInput::SetClipboardText(const char *Text)
void CInput::SetClipboardText(const char *pText)
{
SDL_SetClipboardText(Text);
SDL_SetClipboardText(pText);
}
void CInput::Clear()
@ -163,6 +164,29 @@ bool CInput::KeyState(int Key) const
return m_aInputState[Key];
}
void CInput::UpdateMouseState()
{
const int MouseState = SDL_GetMouseState(NULL, NULL);
if(MouseState & SDL_BUTTON(SDL_BUTTON_LEFT))
m_aInputState[KEY_MOUSE_1] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_RIGHT))
m_aInputState[KEY_MOUSE_2] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_MIDDLE))
m_aInputState[KEY_MOUSE_3] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_X1))
m_aInputState[KEY_MOUSE_4] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_X2))
m_aInputState[KEY_MOUSE_5] = 1;
if(MouseState & SDL_BUTTON(6))
m_aInputState[KEY_MOUSE_6] = 1;
if(MouseState & SDL_BUTTON(7))
m_aInputState[KEY_MOUSE_7] = 1;
if(MouseState & SDL_BUTTON(8))
m_aInputState[KEY_MOUSE_8] = 1;
if(MouseState & SDL_BUTTON(9))
m_aInputState[KEY_MOUSE_9] = 1;
}
bool CInput::GetIMEState()
{
return m_NumTextInputInstances > 0;
@ -231,26 +255,8 @@ int CInput::Update()
if(m_EditingTextLen == 0)
m_EditingTextLen = -1;
// these states must always be updated manually because they are not in the GetKeyState from SDL
const int MouseState = SDL_GetMouseState(NULL, NULL);
if(MouseState & SDL_BUTTON(SDL_BUTTON_LEFT))
m_aInputState[KEY_MOUSE_1] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_RIGHT))
m_aInputState[KEY_MOUSE_2] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_MIDDLE))
m_aInputState[KEY_MOUSE_3] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_X1))
m_aInputState[KEY_MOUSE_4] = 1;
if(MouseState & SDL_BUTTON(SDL_BUTTON_X2))
m_aInputState[KEY_MOUSE_5] = 1;
if(MouseState & SDL_BUTTON(6))
m_aInputState[KEY_MOUSE_6] = 1;
if(MouseState & SDL_BUTTON(7))
m_aInputState[KEY_MOUSE_7] = 1;
if(MouseState & SDL_BUTTON(8))
m_aInputState[KEY_MOUSE_8] = 1;
if(MouseState & SDL_BUTTON(9))
m_aInputState[KEY_MOUSE_9] = 1;
// these states must always be updated manually because they are not in the SDL_GetKeyboardState from SDL
UpdateMouseState();
SDL_Event Event;
bool IgnoreKeys = false;

View file

@ -11,9 +11,6 @@ class CInput : public IEngineInput
{
IEngineGraphics *m_pGraphics;
int m_LastX;
int m_LastY;
int m_InputGrabbed;
char *m_pClipboardText;
@ -31,6 +28,8 @@ class CInput : public IEngineInput
unsigned char m_aInputState[g_MaxKeys]; // SDL_SCANCODE
int m_InputCounter;
void UpdateMouseState();
// IME support
int m_NumTextInputInstances;
char m_aEditingText[INPUT_TEXT_SIZE];
@ -43,6 +42,7 @@ class CInput : public IEngineInput
public:
CInput();
~CInput();
void Init() override;
@ -50,14 +50,15 @@ public:
bool KeyIsPressed(int Key) const override { return KeyState(Key); }
bool KeyPress(int Key, bool CheckCounter) const override { return CheckCounter ? (m_aInputCount[Key] == m_InputCounter) : m_aInputCount[Key]; }
void MouseRelative(float *x, float *y) override;
bool MouseRelative(float *pX, float *pY) override;
void MouseModeAbsolute() override;
void MouseModeRelative() override;
void NativeMousePos(int *x, int *y) const override;
bool NativeMousePressed(int index) override;
void NativeMousePos(int *pX, int *pY) const override;
bool NativeMousePressed(int Index) override;
bool MouseDoubleClick() override;
const char *GetClipboardText() override;
void SetClipboardText(const char *Text) override;
void SetClipboardText(const char *pText) override;
int Update() override;

View file

@ -57,7 +57,6 @@ public:
}
return m_aInputEvents[Index];
}
CEvent *GetEventsRaw() { return m_aInputEvents; }
int *GetEventCountRaw() { return &m_NumEvents; }
@ -68,17 +67,19 @@ public:
const char *KeyName(int Key) const { return (Key >= 0 && Key < g_MaxKeys) ? g_aaKeyStrings[Key] : g_aaKeyStrings[0]; }
virtual void Clear() = 0;
//
virtual void NativeMousePos(int *mx, int *my) const = 0;
virtual bool NativeMousePressed(int index) = 0;
// mouse
virtual void NativeMousePos(int *pX, int *pY) const = 0;
virtual bool NativeMousePressed(int Index) = 0;
virtual void MouseModeRelative() = 0;
virtual void MouseModeAbsolute() = 0;
virtual bool MouseDoubleClick() = 0;
virtual bool MouseRelative(float *pX, float *pY) = 0;
// clipboard
virtual const char *GetClipboardText() = 0;
virtual void SetClipboardText(const char *Text) = 0;
virtual void MouseRelative(float *x, float *y) = 0;
virtual void SetClipboardText(const char *pText) = 0;
// text editing
virtual bool GetIMEState() = 0;
virtual void SetIMEState(bool Activate) = 0;
virtual int GetIMEEditingTextLength() const = 0;

View file

@ -352,8 +352,7 @@ void CGameClient::OnUpdate()
{
// handle mouse movement
float x = 0.0f, y = 0.0f;
Input()->MouseRelative(&x, &y);
if(x != 0.0f || y != 0.0f)
if(Input()->MouseRelative(&x, &y))
{
for(auto &pComponent : m_vpInput)
{