2019-10-27 23:24:09 +00:00
|
|
|
#pragma once
|
|
|
|
|
2019-10-28 05:47:49 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
#include "tarray.h"
|
2019-10-28 00:12:31 +00:00
|
|
|
#include "scancodes.h"
|
2019-11-03 19:24:50 +00:00
|
|
|
#include "c_bind.h"
|
2019-11-04 22:01:50 +00:00
|
|
|
#include "c_buttons.h"
|
2019-11-03 23:53:55 +00:00
|
|
|
#include "d_event.h"
|
2019-11-04 16:58:18 +00:00
|
|
|
#include "osd.h"
|
2019-12-14 19:15:15 +00:00
|
|
|
#include "m_joy.h"
|
|
|
|
#include "gamecvars.h"
|
2019-11-04 16:58:18 +00:00
|
|
|
|
|
|
|
extern char appactive;
|
2019-10-28 00:12:31 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
typedef uint16_t kb_scancode;
|
2019-11-06 22:40:10 +00:00
|
|
|
extern int GUICapture;
|
2019-10-28 05:47:49 +00:00
|
|
|
|
2019-10-27 23:24:09 +00:00
|
|
|
// This encapsulates the entire game-readable input state which previously was spread out across several files.
|
|
|
|
|
2019-10-28 00:12:31 +00:00
|
|
|
enum
|
|
|
|
{
|
2019-10-28 05:47:49 +00:00
|
|
|
MAXMOUSEBUTTONS = 10,
|
2019-10-28 00:12:31 +00:00
|
|
|
};
|
|
|
|
|
2019-11-04 16:58:18 +00:00
|
|
|
extern bool g_mouseGrabbed;
|
|
|
|
extern bool g_mouseEnabled;
|
|
|
|
extern bool g_mouseInsideWindow;
|
|
|
|
extern bool g_mouseLockedToWindow;
|
|
|
|
|
|
|
|
|
2019-10-27 23:24:09 +00:00
|
|
|
|
2019-11-04 00:01:54 +00:00
|
|
|
enum EMouseBits
|
|
|
|
{
|
|
|
|
LEFT_MOUSE = 1,
|
|
|
|
RIGHT_MOUSE = 2,
|
|
|
|
MIDDLE_MOUSE = 4,
|
|
|
|
THUMB_MOUSE = 8,
|
|
|
|
WHEELUP_MOUSE = 16,
|
|
|
|
WHEELDOWN_MOUSE= 32,
|
|
|
|
THUMB2_MOUSE = 64,
|
2019-12-14 16:15:17 +00:00
|
|
|
WHEELLEFT_MOUSE = 128,
|
|
|
|
WHEELRIGHT_MOUSE = 256,
|
2019-11-04 00:01:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
MOUSE_IDLE = 0,
|
|
|
|
MOUSE_PRESSED,
|
|
|
|
MOUSE_HELD,
|
|
|
|
MOUSE_RELEASED,
|
|
|
|
};
|
|
|
|
|
2019-11-10 14:15:14 +00:00
|
|
|
struct ControlInfo
|
|
|
|
{
|
|
|
|
int32_t dx;
|
|
|
|
int32_t dy;
|
|
|
|
int32_t dz;
|
|
|
|
int32_t dyaw;
|
|
|
|
int32_t dpitch;
|
|
|
|
int32_t droll;
|
|
|
|
int32_t mousex;
|
|
|
|
int32_t mousey;
|
|
|
|
};
|
|
|
|
|
2019-11-04 00:01:54 +00:00
|
|
|
|
2019-10-27 23:24:09 +00:00
|
|
|
class InputState
|
|
|
|
{
|
2019-11-03 23:53:55 +00:00
|
|
|
enum
|
|
|
|
{
|
|
|
|
KEYFIFOSIZ = 64,
|
|
|
|
};
|
2019-10-27 23:24:09 +00:00
|
|
|
|
2019-12-23 19:03:03 +00:00
|
|
|
uint8_t KeyStatus[NUM_KEYS];
|
2019-10-28 00:12:31 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
kb_scancode g_keyFIFO[KEYFIFOSIZ];
|
|
|
|
char16_t g_keyAsciiFIFO[KEYFIFOSIZ];
|
2019-11-03 23:53:55 +00:00
|
|
|
uint8_t g_keyFIFOpos;
|
|
|
|
uint8_t g_keyFIFOend;
|
|
|
|
uint8_t g_keyAsciiPos;
|
|
|
|
uint8_t g_keyAsciiEnd;
|
|
|
|
|
|
|
|
kb_scancode KB_LastScan;
|
2019-11-04 00:01:54 +00:00
|
|
|
|
2019-11-10 14:15:14 +00:00
|
|
|
vec2_t g_mousePos;
|
|
|
|
vec2_t g_mouseAbs;
|
|
|
|
|
2019-10-27 23:24:09 +00:00
|
|
|
public:
|
|
|
|
|
2019-10-28 00:12:31 +00:00
|
|
|
uint8_t GetKeyStatus(int key)
|
|
|
|
{
|
|
|
|
return KeyStatus[key];
|
|
|
|
}
|
|
|
|
|
2019-10-28 05:47:49 +00:00
|
|
|
void SetKeyStatus(int key, int state = 1)
|
2019-10-28 00:12:31 +00:00
|
|
|
{
|
|
|
|
KeyStatus[key] = (uint8_t)state;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearKeyStatus(int key)
|
|
|
|
{
|
|
|
|
KeyStatus[key] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearAllKeyStatus()
|
|
|
|
{
|
|
|
|
memset(KeyStatus, 0, sizeof(KeyStatus));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AltPressed()
|
|
|
|
{
|
|
|
|
return KeyStatus[sc_LeftAlt] || KeyStatus[sc_RightAlt];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CtrlPressed()
|
|
|
|
{
|
2019-10-28 05:47:49 +00:00
|
|
|
return KeyStatus[sc_LeftControl] || KeyStatus[sc_RightControl];
|
2019-10-28 00:12:31 +00:00
|
|
|
}
|
2019-10-28 06:02:42 +00:00
|
|
|
|
|
|
|
bool WinPressed()
|
|
|
|
{
|
|
|
|
return KeyStatus[sc_LeftWin] || KeyStatus[sc_RightWin];
|
|
|
|
}
|
2019-10-28 00:12:31 +00:00
|
|
|
|
|
|
|
bool ShiftPressed()
|
|
|
|
{
|
|
|
|
return KeyStatus[sc_LeftShift] || KeyStatus[sc_RightShift];
|
|
|
|
}
|
2019-10-28 06:02:42 +00:00
|
|
|
|
2019-10-28 00:12:31 +00:00
|
|
|
bool EscapePressed()
|
|
|
|
{
|
|
|
|
return !!KeyStatus[sc_Escape];
|
|
|
|
}
|
2019-10-27 23:24:09 +00:00
|
|
|
|
2019-10-28 06:10:56 +00:00
|
|
|
void SetBindsEnabled(bool on)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
bool keyBufferWaiting()
|
|
|
|
{
|
|
|
|
return (g_keyAsciiPos != g_keyAsciiEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
int keyBufferFull(void)
|
|
|
|
{
|
|
|
|
return ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1)) == g_keyAsciiPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
void keySetState(int32_t key, int32_t state)
|
|
|
|
{
|
2019-11-03 23:55:49 +00:00
|
|
|
if (state && !GetKeyStatus(key))
|
|
|
|
{
|
|
|
|
KB_LastScan = key;
|
|
|
|
}
|
|
|
|
|
2019-11-03 23:53:55 +00:00
|
|
|
SetKeyStatus(key, state);
|
|
|
|
if (state)
|
|
|
|
{
|
|
|
|
g_keyFIFO[g_keyFIFOend] = key;
|
|
|
|
g_keyFIFO[(g_keyFIFOend + 1) & (KEYFIFOSIZ - 1)] = state;
|
|
|
|
g_keyFIFOend = ((g_keyFIFOend + 2) & (KEYFIFOSIZ - 1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
kb_scancode keyGetScan()
|
2019-11-03 23:53:55 +00:00
|
|
|
{
|
|
|
|
if (g_keyFIFOpos == g_keyFIFOend)
|
|
|
|
return 0;
|
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
auto const c = g_keyFIFO[g_keyFIFOpos];
|
2019-11-03 23:53:55 +00:00
|
|
|
g_keyFIFOpos = ((g_keyFIFOpos + 2) & (KEYFIFOSIZ - 1));
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
void keyFlushScans(void)
|
|
|
|
{
|
2019-11-04 16:58:18 +00:00
|
|
|
memset(&g_keyFIFO, 0, sizeof(g_keyFIFO));
|
2019-11-03 23:53:55 +00:00
|
|
|
g_keyFIFOpos = g_keyFIFOend = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// character-based input functions
|
|
|
|
//
|
|
|
|
char keyGetChar(void)
|
|
|
|
{
|
|
|
|
if (g_keyAsciiPos == g_keyAsciiEnd)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
char const c = g_keyAsciiFIFO[g_keyAsciiPos];
|
|
|
|
g_keyAsciiPos = ((g_keyAsciiPos + 1) & (KEYFIFOSIZ - 1));
|
|
|
|
|
|
|
|
return c;
|
|
|
|
}
|
2019-11-03 23:55:49 +00:00
|
|
|
|
|
|
|
void keySetChar(int key)
|
|
|
|
{
|
2019-12-24 11:59:26 +00:00
|
|
|
g_keyAsciiFIFO[g_keyAsciiEnd] = (char16_t)key;
|
2019-11-03 23:55:49 +00:00
|
|
|
g_keyAsciiEnd = ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1));
|
|
|
|
}
|
2019-11-03 23:53:55 +00:00
|
|
|
|
|
|
|
void keyFlushChars(void)
|
|
|
|
{
|
2019-11-04 16:58:18 +00:00
|
|
|
memset(&g_keyAsciiFIFO, 0, sizeof(g_keyAsciiFIFO));
|
2019-11-03 23:53:55 +00:00
|
|
|
g_keyAsciiPos = g_keyAsciiEnd = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool UnboundKeyPressed(int scan)
|
|
|
|
{
|
|
|
|
return (GetKeyStatus(scan) != 0 && Bindings.GetBind(scan) == nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
kb_scancode GetLastScanCode()
|
|
|
|
{
|
|
|
|
return (KB_LastScan);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetLastScanCode(kb_scancode scancode)
|
|
|
|
{
|
|
|
|
KB_LastScan = (scancode);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearLastScanCode()
|
|
|
|
{
|
|
|
|
KB_LastScan = sc_None;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ClearKeysDown(void)
|
|
|
|
{
|
|
|
|
KB_LastScan = 0;
|
|
|
|
ClearAllKeyStatus();
|
|
|
|
}
|
2019-11-03 23:55:49 +00:00
|
|
|
|
2019-11-10 14:15:14 +00:00
|
|
|
void AddEvent(const event_t* ev);
|
2019-11-03 23:53:55 +00:00
|
|
|
|
2019-11-10 14:15:14 +00:00
|
|
|
void MouseSetPos(int x, int y)
|
|
|
|
{
|
|
|
|
g_mousePos = { x, y };
|
|
|
|
}
|
|
|
|
void MouseAddToPos(int x, int y)
|
|
|
|
{
|
|
|
|
g_mousePos.x += x;
|
|
|
|
g_mousePos.y += y;
|
|
|
|
}
|
|
|
|
void MouseSetAbs(int x, int y)
|
|
|
|
{
|
|
|
|
g_mouseAbs = { x, y };
|
|
|
|
}
|
2019-12-14 19:15:15 +00:00
|
|
|
|
|
|
|
bool gamePadActive()
|
|
|
|
{
|
|
|
|
// fixme: This needs to be tracked.
|
|
|
|
return false;
|
|
|
|
}
|
2019-11-10 14:15:14 +00:00
|
|
|
int32_t mouseReadAbs(vec2_t* const pResult);
|
|
|
|
void GetMouseDelta(ControlInfo* info);
|
|
|
|
|
2019-11-28 18:35:35 +00:00
|
|
|
void ClearAllInput()
|
|
|
|
{
|
|
|
|
ClearKeysDown();
|
|
|
|
keyFlushChars();
|
|
|
|
keyFlushScans();
|
2019-12-24 11:59:26 +00:00
|
|
|
buttonMap.ResetButtonStates(); // this is important. If all input is cleared, the buttons must be cleared as well.
|
|
|
|
}
|
|
|
|
|
|
|
|
bool CheckAllInput()
|
|
|
|
{
|
|
|
|
auto res = keyGetScan();
|
|
|
|
ClearAllInput();
|
|
|
|
return res;
|
2019-11-28 18:35:35 +00:00
|
|
|
}
|
|
|
|
|
2019-10-27 23:24:09 +00:00
|
|
|
};
|
|
|
|
|
2019-12-14 19:15:15 +00:00
|
|
|
extern InputState inputState;
|
|
|
|
|
|
|
|
inline void CONTROL_GetInput(ControlInfo* info)
|
|
|
|
{
|
|
|
|
memset(info, 0, sizeof(ControlInfo));
|
|
|
|
|
|
|
|
if (in_mouse)
|
|
|
|
inputState.GetMouseDelta(info);
|
|
|
|
|
|
|
|
if (in_joystick)
|
|
|
|
{
|
|
|
|
// Handle joysticks/game controllers.
|
|
|
|
float joyaxes[NUM_JOYAXIS];
|
|
|
|
|
|
|
|
I_GetAxes(joyaxes);
|
|
|
|
|
|
|
|
info->dyaw += joyaxes[JOYAXIS_Yaw];
|
|
|
|
info->dx += joyaxes[JOYAXIS_Side];
|
|
|
|
info->dz += joyaxes[JOYAXIS_Forward];
|
|
|
|
info->dpitch += joyaxes[JOYAXIS_Pitch];
|
|
|
|
}
|
|
|
|
}
|
2019-11-06 18:22:14 +00:00
|
|
|
|
2019-12-24 11:59:26 +00:00
|
|
|
#define WIN_IS_PRESSED ( inputState.WinPressed() )
|
|
|
|
#define ALT_IS_PRESSED ( inputState.AltPressed() )
|
|
|
|
#define SHIFTS_IS_PRESSED ( inputState.ShiftPressed() )
|