256 lines
5.9 KiB
C++
256 lines
5.9 KiB
C++
#include "Aeon/Input/Input.hpp"
|
|
|
|
#include <iostream>
|
|
#include <algorithm>
|
|
#include <iterator>
|
|
#include <bitset>
|
|
#include <iomanip>
|
|
|
|
#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<const uint8_t*>(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<const uint8_t*>(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 = KeyCodeFromSDL(keycode);
|
|
if ( mEvent.key.state == SDL_PRESSED )
|
|
{
|
|
e.Type = "KEYBOARD_KEYDOWN";
|
|
}
|
|
else if ( mEvent.key.state == SDL_RELEASED )
|
|
{
|
|
e.Type = "KEYBOARD_KEYUP";
|
|
}
|
|
|
|
uint16_t mods = mEvent.key.keysym.mod;
|
|
e.keyMods = mods;
|
|
|
|
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 );
|
|
// }
|
|
// }
|
|
}
|