#include "Aeon/Input/Input.hpp" #include #include #include #include "Aeon/Core/Events.hpp" #include "Aeon/Input/InputMap.hpp" #include "Aeon/Rendering/ImGui.hpp" using Aeon::Input::Input; Input::Input() : mEvent() , mDisplayEventDispatcher() , mKeyboardEventDispatcher() , mMouseEventDispatcher() { mDisplayEventDispatcher.RegisterAsSource( "ENGINE_DISPLAY_CORE" ); mMouseEventDispatcher.RegisterAsSource( "ENGINE_INPUT_MOUSE" ); mKeyboardEventDispatcher.RegisterAsSource( "ENGINE_INPUT_KEYBOARD" ); mKbdState = static_cast(SDL_GetKeyboardState( &mNumScancodes )); } Input::~Input() { mDisplayEventDispatcher.DeRegisterAsSource( "ENGINE_DISPLAY_CORE" ); mMouseEventDispatcher.DeRegisterAsSource( "ENGINE_INPUT_MOUSE" ); mKeyboardEventDispatcher.DeRegisterAsSource( "ENGINE_INPUT_KEYBOARD" ); // Do not free mKbdState as that is done by SDL } void Input::PollInput() { //SDL_PumpEvents(); while ( SDL_PollEvent( &mEvent ) ) { // Provide to non-event driven subsystem ImGui_ImplSDL2_ProcessEvent( &mEvent ); switch ( mEvent.type ) { case SDL_WINDOWEVENT: { mPollDisplay(); break; } case SDL_MOUSEWHEEL: { mPollScroll(); break; } case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { mPollClick(); break; } case SDL_MOUSEMOTION: { mPollMouse(); break; } case SDL_KEYDOWN: case SDL_KEYUP: { mPollKeyboard(); } } } // just in case mKbdState = static_cast(SDL_GetKeyboardState( &mNumScancodes )); // keyboard processing mPollScanKeyboard(); } void Input::mPollDisplay() { switch ( mEvent.window.event ) { case SDL_WINDOWEVENT_SHOWN: { mDisplayEventDispatcher.Dispatch( "DISPLAY_SHOW" ); break; } case SDL_WINDOWEVENT_HIDDEN: { mDisplayEventDispatcher.Dispatch( "DISPLAY_HIDE" ); break; } case SDL_WINDOWEVENT_MOVED: { Aeon::Core::GenericEvent e; e.x = mEvent.window.data1; e.y = mEvent.window.data2; e.Type = "DISPLAY_MOVE"; mDisplayEventDispatcher.Dispatch( e ); break; } case SDL_WINDOWEVENT_RESIZED: { Aeon::Core::GenericEvent e; e.x = mEvent.window.data1; e.y = mEvent.window.data2; e.Type = "DISPLAY_RESIZE"; mDisplayEventDispatcher.Dispatch( e ); break; } case SDL_WINDOWEVENT_MINIMIZED: { mDisplayEventDispatcher.Dispatch( "DISPLAY_MINIMISED" ); break; } case SDL_WINDOWEVENT_MAXIMIZED: { mDisplayEventDispatcher.Dispatch( "DISPLAY_MAXIMISED" ); break; } case SDL_WINDOWEVENT_ENTER: { mDisplayEventDispatcher.Dispatch( "DISPLAY_MOUSE_ENTER" ); break; } case SDL_WINDOWEVENT_LEAVE: { mDisplayEventDispatcher.Dispatch( "DISPLAY_MOUSE_LEAVE" ); break; } case SDL_WINDOWEVENT_FOCUS_GAINED: { mDisplayEventDispatcher.Dispatch( "DISPLAY_FOCUS" ); break; } case SDL_WINDOWEVENT_FOCUS_LOST: { mDisplayEventDispatcher.Dispatch( "DISPLAY_OUT_OF_FOCUS" ); break; } case SDL_WINDOWEVENT_CLOSE: { mDisplayEventDispatcher.Dispatch( "DISPLAY_CLOSED" ); break; } } } void Input::mPollMouse() { Aeon::Core::GenericEvent e; e.x = mEvent.motion.x; e.y = mEvent.motion.y; e.dx = mEvent.motion.xrel; e.dy = mEvent.motion.yrel; e.Type = "MOUSE_MOVE"; mMouseEventDispatcher.Dispatch( e ); } void Input::mPollScroll() { Aeon::Core::GenericEvent e; e.y = mEvent.wheel.y; e.Type = "MOUSE_SCROLL"; mMouseEventDispatcher.Dispatch( e ); } void Input::mPollClick() { if ( mEvent.button.state == SDL_PRESSED ) { switch ( mEvent.button.button ) { case SDL_BUTTON_LEFT: { mDisplayEventDispatcher.Dispatch( "MOUSE_LEFT_DOWN" ); break; } case SDL_BUTTON_RIGHT: { mDisplayEventDispatcher.Dispatch( "MOUSE_RIGHT_DOWN" ); break; } case SDL_BUTTON_MIDDLE: { mDisplayEventDispatcher.Dispatch( "MOUSE_MIDDLE_DOWN" ); break; } } } else if ( mEvent.button.state == SDL_RELEASED ) { switch ( mEvent.button.button ) { case SDL_BUTTON_LEFT: { mDisplayEventDispatcher.Dispatch( "MOUSE_LEFT_UP" ); break; } case SDL_BUTTON_RIGHT: { mDisplayEventDispatcher.Dispatch( "MOUSE_RIGHT_UP" ); break; } case SDL_BUTTON_MIDDLE: { mDisplayEventDispatcher.Dispatch( "MOUSE_MIDDLE_UP" ); break; } } } } void Input::mPollKeyboard() { EKeyCode keycode = KeyCodeFromSDL( mEvent.key.keysym.sym ); Aeon::Core::GenericEvent e; e.keyCode = keycode; if ( mEvent.key.state == SDL_PRESSED ) { e.Type = "KEYBOARD_KEYDOWN"; } else if ( mEvent.key.state == SDL_RELEASED ) { e.Type = "KEYBOARD_KEYUP"; } mKeyboardEventDispatcher.Dispatch( e ); } void Input::mPollScanKeyboard() { // this is naive, can be optimised with double buffering for ( int i = 0; i < mNumScancodes; i++ ) { bool isKeyPressed = (bool)mKbdState[i]; if ( isKeyPressed ) { EKeyCode whatKeyPressed = KeyCodeFromScanCode( (SDL_Scancode)i ); Aeon::Core::GenericEvent e; e.keyCode = whatKeyPressed; e.Type = "KEYBOARD_KEYPRESS"; mKeyboardEventDispatcher.Dispatch( e ); } } }