diff options
Diffstat (limited to 'src/engine/client/input.cpp')
| -rw-r--r-- | src/engine/client/input.cpp | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/engine/client/input.cpp b/src/engine/client/input.cpp new file mode 100644 index 00000000..9f546226 --- /dev/null +++ b/src/engine/client/input.cpp @@ -0,0 +1,208 @@ +// copyright (c) 2007 magnus auvinen, see licence.txt for more info +#include "SDL.h" + +#include <base/system.h> +#include <engine/shared/config.h> +#include <engine/graphics.h> +#include <engine/input.h> +#include <engine/keys.h> + +#include "input.h" + +//print >>f, "int inp_key_code(const char *key_name) { int i; if (!strcmp(key_name, \"-?-\")) return -1; else for (i = 0; i < 512; i++) if (!strcmp(key_strings[i], key_name)) return i; return -1; }" + +// this header is protected so you don't include it from anywere +#define KEYS_INCLUDE +#include "keynames.h" +#undef KEYS_INCLUDE + +void CInput::AddEvent(int Unicode, int Key, int Flags) +{ + if(m_NumEvents != INPUT_BUFFER_SIZE) + { + m_aInputEvents[m_NumEvents].m_Unicode = Unicode; + m_aInputEvents[m_NumEvents].m_Key = Key; + m_aInputEvents[m_NumEvents].m_Flags = Flags; + m_NumEvents++; + } +} + +CInput::CInput() +{ + mem_zero(m_aInputCount, sizeof(m_aInputCount)); + mem_zero(m_aInputState, sizeof(m_aInputState)); + mem_zero(m_Keys, sizeof(m_Keys)); + + m_InputCurrent = 0; + m_InputGrabbed = 0; + + m_LastRelease = 0; + m_ReleaseDelta = -1; + + m_NumEvents = 0; +} + +void CInput::Init() +{ + m_pGraphics = Kernel()->RequestInterface<IEngineGraphics>(); + SDL_EnableUNICODE(1); + SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); +} + +void CInput::MouseRelative(int *x, int *y) +{ + int nx = 0, ny = 0; + float Sens = g_Config.m_InpMousesens/100.0f; + + if(g_Config.m_InpGrab) + SDL_GetRelativeMouseState(&nx, &ny); + else + { + if(m_InputGrabbed) + { + SDL_GetMouseState(&nx,&ny); + SDL_WarpMouse(Graphics()->ScreenWidth()/2,Graphics()->ScreenHeight()/2); + nx -= Graphics()->ScreenWidth()/2; ny -= Graphics()->ScreenHeight()/2; + } + } + + *x = nx*Sens; + *y = ny*Sens; +} + +void CInput::MouseModeAbsolute() +{ + SDL_ShowCursor(1); + m_InputGrabbed = 0; + if(g_Config.m_InpGrab) + SDL_WM_GrabInput(SDL_GRAB_OFF); +} + +void CInput::MouseModeRelative() +{ + SDL_ShowCursor(0); + m_InputGrabbed = 1; + if(g_Config.m_InpGrab) + SDL_WM_GrabInput(SDL_GRAB_ON); +} + +int CInput::MouseDoubleClick() +{ + return m_ReleaseDelta < (time_freq() >> 2); +} + +void CInput::ClearKeyStates() +{ + mem_zero(m_aInputState, sizeof(m_aInputState)); + mem_zero(m_aInputCount, sizeof(m_aInputCount)); +} + +int CInput::KeyState(int Key) +{ + return m_aInputState[m_InputCurrent][Key]; +} + +void CInput::Update() +{ + if(m_InputGrabbed && !Graphics()->WindowActive()) + MouseModeAbsolute(); + + /*if(!input_grabbed && Graphics()->WindowActive()) + Input()->MouseModeRelative();*/ + + // clear and begin count on the other one + m_InputCurrent^=1; + mem_zero(&m_aInputCount[m_InputCurrent], sizeof(m_aInputCount[m_InputCurrent])); + mem_zero(&m_aInputState[m_InputCurrent], sizeof(m_aInputState[m_InputCurrent])); + + { + int i; + Uint8 *pState = SDL_GetKeyState(&i); + if(i >= KEY_LAST) + i = KEY_LAST-1; + mem_copy(m_aInputState[m_InputCurrent], pState, i); + } + + // these states must always be updated manually because they are not in the GetKeyState from SDL + int i = SDL_GetMouseState(NULL, NULL); + if(i&SDL_BUTTON(1)) m_aInputState[m_InputCurrent][KEY_MOUSE_1] = 1; // 1 is left + if(i&SDL_BUTTON(3)) m_aInputState[m_InputCurrent][KEY_MOUSE_2] = 1; // 3 is right + if(i&SDL_BUTTON(2)) m_aInputState[m_InputCurrent][KEY_MOUSE_3] = 1; // 2 is middle + if(i&SDL_BUTTON(4)) m_aInputState[m_InputCurrent][KEY_MOUSE_4] = 1; + if(i&SDL_BUTTON(5)) m_aInputState[m_InputCurrent][KEY_MOUSE_5] = 1; + if(i&SDL_BUTTON(6)) m_aInputState[m_InputCurrent][KEY_MOUSE_6] = 1; + if(i&SDL_BUTTON(7)) m_aInputState[m_InputCurrent][KEY_MOUSE_7] = 1; + if(i&SDL_BUTTON(8)) m_aInputState[m_InputCurrent][KEY_MOUSE_8] = 1; + + { + SDL_Event Event; + + while(SDL_PollEvent(&Event)) + { + int Key = -1; + int Action = IInput::FLAG_PRESS; + switch (Event.type) + { + // handle keys + case SDL_KEYDOWN: + AddEvent(Event.key.keysym.unicode, 0, 0); // ignore_convention + if(Event.key.keysym.unicode != 0 && Event.key.keysym.unicode < 256) // ignore_convention + { + Key = Event.key.keysym.unicode; // ignore_convention + m_Keys[Event.key.keysym.sym] = Event.key.keysym.unicode; // ignore_convention + } + else + Key = Event.key.keysym.sym; // ignore_convention + break; + case SDL_KEYUP: + Action = IInput::FLAG_RELEASE; + if(m_Keys[Event.key.keysym.sym] != 0) // ignore_convention + Key = m_Keys[Event.key.keysym.sym]; // ignore_convention + else + Key = Event.key.keysym.sym; // ignore_convention + break; + + // handle mouse buttons + case SDL_MOUSEBUTTONUP: + Action = IInput::FLAG_RELEASE; + + if(Event.button.button == 1) // ignore_convention + { + m_ReleaseDelta = time_get() - m_LastRelease; + m_LastRelease = time_get(); + } + + // fall through + case SDL_MOUSEBUTTONDOWN: + if(Event.button.button == SDL_BUTTON_LEFT) Key = KEY_MOUSE_1; // ignore_convention + if(Event.button.button == SDL_BUTTON_RIGHT) Key = KEY_MOUSE_2; // ignore_convention + if(Event.button.button == SDL_BUTTON_MIDDLE) Key = KEY_MOUSE_3; // ignore_convention + if(Event.button.button == SDL_BUTTON_WHEELUP) Key = KEY_MOUSE_WHEEL_UP; // ignore_convention + if(Event.button.button == SDL_BUTTON_WHEELDOWN) Key = KEY_MOUSE_WHEEL_DOWN; // ignore_convention + if(Event.button.button == 6) Key = KEY_MOUSE_6; // ignore_convention + if(Event.button.button == 7) Key = KEY_MOUSE_7; // ignore_convention + if(Event.button.button == 8) Key = KEY_MOUSE_8; // ignore_convention + break; + + // other messages + case SDL_QUIT: + // TODO: cleaner exit + exit(0); // ignore_convention + break; + } + + // + if(Key != -1) + { + m_aInputCount[m_InputCurrent][Key].m_Presses++; + if(Action == IInput::FLAG_PRESS) + m_aInputState[m_InputCurrent][Key] = 1; + AddEvent(0, Key, Action); + } + + } + } +} + + +IEngineInput *CreateEngineInput() { return new CInput; } |