#include "../FUNCTION.H" #include "UserInput.h" extern KeyboardClass * Keyboard; std::map sdl_keyMapping_reverse; UserInputClass::UserInputClass() { LastAction = InputAction::INPUT_ACTION_NONE; // generate reverse keymapping for ( auto it = sdl_keyMapping.begin(); it != sdl_keyMapping.end(); it++ ) { sdl_keyMapping_reverse[it->second] = it->first; } } bool UserInputClass::KeyboardState::Key_Down(KeyNumType key) const { auto sdl_Key = sdl_keyMapping_reverse.find( key ); if ( sdl_Key != sdl_keyMapping_reverse.end() ) { const Uint8* keyState = SDL_GetKeyboardState(NULL); return keyState[ sdl_Key->second ]; } return false; } bool UserInputClass::MouseState::Mouse_Down(KeyNumType key) const { // get mouse state, we are only interested in the buttons const Uint32 MouseState = SDL_GetMouseState(NULL,NULL); switch (key) { case KN_LMOUSE: return MouseState & SDL_BUTTON(SDL_BUTTON_LEFT); break; case KN_RMOUSE: return MouseState & SDL_BUTTON(SDL_BUTTON_RIGHT); break; } } void UserInputClass::Process_Input(KeyNumType& key, int& flags) { bool leftMouseProcessed = false; const Uint32 MouseState = SDL_GetMouseState(&Mouse.X, &Mouse.Y); Keyboard->MouseQX = Mouse.X; Keyboard->MouseQY = Mouse.Y; static SDL_Event event; memset(&event, 0, sizeof(SDL_Event)); while (SDL_PollEvent(&event)) { const Uint8* state = SDL_GetKeyboardState(NULL); switch (event.type) { case SDL_SYSWMEVENT: if (event.syswm.msg->msg.win.msg == WM_DESTROY) { Invalidate_Cached_Icons(); VisiblePage.Un_Init(); HiddenPage.Un_Init(); AllSurfaces.Release(); if (!InDebugger) Reset_Video_Mode(); PostQuitMessage(0); switch (ReadyToQuit) { case 1: ReadyToQuit = 2; break; case 0: ExitProcess(0); break; } } break; /* Mouse is moving */ case SDL_MOUSEMOTION: if ( !( MouseState & SDL_BUTTON(SDL_BUTTON_LEFT) ) ) { flags = GadgetClass::LEFTUP; } break; case SDL_MOUSEBUTTONDOWN: if (event.button.button == SDL_BUTTON_LEFT) { Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_DOWN; key = KN_LMOUSE; flags = GadgetClass::LEFTPRESS; EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE) ); Keyboard->Put_Element(KN_LMOUSE); leftMouseProcessed = true; numFramesLMouse++; // after first left-mouse down, abort handling any other SDL events // because game might first need to switch into rubber band mode if (numFramesLMouse == 1) return; } else if (event.button.button == SDL_BUTTON_RIGHT) { Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_DOWN; EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_RMOUSE) ); Keyboard->Put_Element(KN_RMOUSE); key = KN_RMOUSE; flags = GadgetClass::RIGHTPRESS; numFramesLMouse = 0; } break; case SDL_MOUSEBUTTONUP: if (event.button.button == SDL_BUTTON_LEFT) { Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_RELEASE; EventQueue.Put(new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE)); flags = GadgetClass::LEFTRELEASE; numFramesLMouse = 0; } else if (event.button.button == SDL_BUTTON_RIGHT) { Mouse.Button_Right == MouseButtonState::MOUSE_BUTTON_RELEASE; EventQueue.Put( new MouseEventMessage(Mouse.X, Mouse.Y, KN_RMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_RELEASE) ); flags = GadgetClass::RIGHTRELEASE; numFramesLMouse = 0; } break; case SDL_KEYDOWN: { if (event.key.keysym.scancode == SDL_SCANCODE_GRAVE) { renderConsole = !renderConsole; if (renderConsole) { ShowCursor(TRUE); Hide_Mouse(); } else { ShowCursor(FALSE); Show_Mouse(); } break; } int keyFlags = 0x00; if (state[SDL_SCANCODE_RSHIFT] || state[SDL_SCANCODE_LSHIFT]) { KeyB.Shift = true; keyFlags |= KN_SHIFT_BIT; } if (state[SDL_SCANCODE_RALT] || state[SDL_SCANCODE_LALT]) { keyFlags |= KN_ALT_BIT; KeyB.Alt = true; } if (state[SDL_SCANCODE_RCTRL] || state[SDL_SCANCODE_LCTRL]) { keyFlags |= KN_CTRL_BIT; KeyB.Control = true; } if (state[SDL_SCANCODE_CAPSLOCK]) { keyFlags |= KN_CAPSLOCK_BIT; KeyB.CapsLock = true; } // handle match between SDL and internals (non-text keys) auto element = sdl_keyMapping.find((SDL_KeyCode)event.key.keysym.sym); if (element != sdl_keyMapping.end()) { //EventQueue.Put( element->second | keyFlags ); EventQueue.Put( new KeyboardEventMessage( (KeyNumType)element->second, KeyB.Shift, KeyB.Alt, KeyB.Control, KeyB.CapsLock ) ); Keyboard->Put_Element( element->second | keyFlags); KeyB.ASCII = element->second; } break; } case SDL_TEXTINPUT: // limit to range 0-255 if (event.text.text[0] == ( event.text.text[0] & 0xFF ) ) { KeyB.ASCII = (char)event.text.text[0]; } } if (Debug_Map || renderConsole) { ImGui_ImplSDL2_ProcessEvent(&event); } } if (!leftMouseProcessed && numFramesLMouse != 0) { Mouse.Button_Left == MouseButtonState::MOUSE_BUTTON_HOLD; flags = GadgetClass::LEFTHELD; EventQueue.Put(new MouseEventMessage(Mouse.X, Mouse.Y, KN_LMOUSE, UserInputClass::MouseButtonState::MOUSE_BUTTON_HOLD)); } }