raze-gles/source/common/inputstate.h

345 lines
5.9 KiB
C++

#pragma once
#include <stdint.h>
#include "tarray.h"
#include "scancodes.h"
#include "c_bind.h"
#include "c_buttons.h"
#include "d_event.h"
#include "osd.h"
#include "m_joy.h"
#include "gamecvars.h"
extern char appactive;
typedef uint8_t kb_scancode;
extern int GUICapture;
// This encapsulates the entire game-readable input state which previously was spread out across several files.
enum
{
NUMKEYS = 256,
MAXMOUSEBUTTONS = 10,
};
extern bool g_mouseGrabbed;
extern bool g_mouseEnabled;
extern bool g_mouseInsideWindow;
extern bool g_mouseLockedToWindow;
enum EMouseBits
{
LEFT_MOUSE = 1,
RIGHT_MOUSE = 2,
MIDDLE_MOUSE = 4,
THUMB_MOUSE = 8,
WHEELUP_MOUSE = 16,
WHEELDOWN_MOUSE= 32,
THUMB2_MOUSE = 64,
WHEELLEFT_MOUSE = 128,
WHEELRIGHT_MOUSE = 256,
};
enum
{
MOUSE_IDLE = 0,
MOUSE_PRESSED,
MOUSE_HELD,
MOUSE_RELEASED,
};
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;
};
class InputState
{
enum
{
KEYFIFOSIZ = 64,
};
uint8_t KeyStatus[NUMKEYS];
char g_keyFIFO[KEYFIFOSIZ];
char g_keyAsciiFIFO[KEYFIFOSIZ];
uint8_t g_keyFIFOpos;
uint8_t g_keyFIFOend;
uint8_t g_keyAsciiPos;
uint8_t g_keyAsciiEnd;
kb_scancode KB_LastScan;
int g_mouseBits;
uint8_t g_mouseClickState;
vec2_t g_mousePos;
vec2_t g_mouseAbs;
public:
uint8_t GetKeyStatus(int key)
{
return KeyStatus[key];
}
void SetKeyStatus(int key, int state = 1)
{
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()
{
return KeyStatus[sc_LeftControl] || KeyStatus[sc_RightControl];
}
bool WinPressed()
{
return KeyStatus[sc_LeftWin] || KeyStatus[sc_RightWin];
}
bool ShiftPressed()
{
return KeyStatus[sc_LeftShift] || KeyStatus[sc_RightShift];
}
bool EscapePressed()
{
return !!KeyStatus[sc_Escape];
}
void SetBindsEnabled(bool on)
{
}
bool keyBufferWaiting()
{
return (g_keyAsciiPos != g_keyAsciiEnd);
}
int keyBufferFull(void)
{
return ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1)) == g_keyAsciiPos;
}
void keyBufferInsert(char code)
{
g_keyAsciiFIFO[g_keyAsciiEnd] = code;
g_keyAsciiEnd = ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1));
}
void keySetState(int32_t key, int32_t state)
{
if (state && !GetKeyStatus(key))
{
KB_LastScan = key;
}
SetKeyStatus(key, state);
event_t ev = { (uint8_t)(state ? EV_KeyDown : EV_KeyUp), 0, (int16_t)key };
if (state)
{
g_keyFIFO[g_keyFIFOend] = key;
g_keyFIFO[(g_keyFIFOend + 1) & (KEYFIFOSIZ - 1)] = state;
g_keyFIFOend = ((g_keyFIFOend + 2) & (KEYFIFOSIZ - 1));
}
}
char keyGetScan(void)
{
if (g_keyFIFOpos == g_keyFIFOend)
return 0;
char const c = g_keyFIFO[g_keyFIFOpos];
g_keyFIFOpos = ((g_keyFIFOpos + 2) & (KEYFIFOSIZ - 1));
return c;
}
void keyFlushScans(void)
{
memset(&g_keyFIFO, 0, sizeof(g_keyFIFO));
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;
}
void keySetChar(int key)
{
g_keyAsciiFIFO[g_keyAsciiEnd] = key;
g_keyAsciiEnd = ((g_keyAsciiEnd + 1) & (KEYFIFOSIZ - 1));
}
void keyFlushChars(void)
{
memset(&g_keyAsciiFIFO, 0, sizeof(g_keyAsciiFIFO));
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();
}
void mouseSetBit(int val, int state)
{
if (state) g_mouseBits |= val;
else g_mouseBits &=~val;
}
void handleevents_updatemousestate(uint8_t state)
{
g_mouseClickState = state == EV_KeyUp ? MOUSE_RELEASED : MOUSE_PRESSED;
}
void AddEvent(const event_t* ev);
int32_t mouseReadButtons(void)
{
return (!g_mouseEnabled || !appactive || !g_mouseInsideWindow || GUICapture) ? 0 : g_mouseBits;
}
int mouseClickState()
{
return g_mouseClickState;
}
void clearMouseClickState()
{
g_mouseClickState = MOUSE_IDLE;
}
int32_t mouseAdvanceClickState(void)
{
switch (g_mouseClickState)
{
case MOUSE_PRESSED: g_mouseClickState = MOUSE_HELD; return 1;
case MOUSE_RELEASED: g_mouseClickState = MOUSE_IDLE; return 1;
case MOUSE_HELD: return 1;
}
return 0;
}
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 };
}
bool gamePadActive()
{
// fixme: This needs to be tracked.
return false;
}
int32_t MouseGetButtons(void) { return mouseReadButtons(); }
inline void MouseClearButton(int32_t b) { g_mouseBits &= ~b; }
inline void MouseClearAllButtonss(void) { g_mouseBits = 0; }
int32_t mouseReadAbs(vec2_t* const pResult);
void GetMouseDelta(ControlInfo* info);
void ClearAllInput()
{
ClearKeysDown();
keyFlushChars();
keyFlushScans();
}
};
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];
}
}