// copyright (c) 2007 magnus auvinen, see licence.txt for more info #include "SDL.h" #include #include #include #include #include #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)); m_InputCurrent = 0; m_InputGrabbed = 0; m_LastRelease = 0; m_ReleaseDelta = -1; m_NumEvents = 0; } void CInput::Init() { m_pGraphics = Kernel()->RequestInterface(); 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 = (int)(nx*Sens); *y = (int)(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() { if(m_ReleaseDelta >= 0 && m_ReleaseDelta < (time_freq() >> 2)) { m_LastRelease = 0; m_ReleaseDelta = -1; return 1; } return 0; } 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: if(Event.key.keysym.unicode < 255) // ignore_convention AddEvent(Event.key.keysym.unicode, 0, 0); // ignore_convention Key = Event.key.keysym.sym; // ignore_convention break; case SDL_KEYUP: Action = IInput::FLAG_RELEASE; 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; }