Move SDL helpers to their own package in extern/, allow conversion from sdl to ois keycodes, (maybe) fix unicode handling

actorid
Jordan Milne 12 years ago
parent cb01df49c0
commit ed644259ce

@ -474,6 +474,7 @@ endif(WIN32)
# Extern
add_subdirectory (extern/shiny)
add_subdirectory (extern/oics)
add_subdirectory (extern/sdl4ogre)
# Components
add_subdirectory (components)

@ -20,7 +20,7 @@ add_openmw_dir (mwrender
)
add_openmw_dir (mwinput
inputmanagerimp sdlinputwrapper
inputmanagerimp
)
add_openmw_dir (mwgui
@ -108,6 +108,7 @@ target_link_libraries(openmw
"shiny"
"shiny.OgrePlatform"
"oics"
"sdl4ogre"
components
)

@ -62,13 +62,13 @@ namespace MWInput
Ogre::RenderWindow* window = ogre.getWindow ();
mInputManager = new MWSDLInputWrapper(window);
mInputManager = new SFO::InputWrapper(window);
mInputManager->setMouseEventCallback (this);
mInputManager->setKeyboardEventCallback (this);
mInputManager->setWindowEventCallback(this);
std::string file = userFileExists ? userFile : "";
mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
mInputBinder = new ICS::InputControlSystem(file, true, this, NULL, A_Last);
adjustMouseRegion (window->getWidth(), window->getHeight());
@ -78,7 +78,7 @@ namespace MWInput
for (int i = 0; i < A_Last; ++i)
{
mInputCtrl->getChannel (i)->addListener (this);
mInputBinder->getChannel (i)->addListener (this);
}
mControlSwitch["playercontrols"] = true;
@ -94,9 +94,9 @@ namespace MWInput
InputManager::~InputManager()
{
mInputCtrl->save (mUserFile);
mInputBinder->save (mUserFile);
delete mInputCtrl;
delete mInputBinder;
delete mInputManager;
}
@ -206,7 +206,7 @@ namespace MWInput
// update values of channels (as a result of pressed keys)
if (!loading)
mInputCtrl->update(dt);
mInputBinder->update(dt);
// Update windows/gui as a result of input events
// For instance this could mean opening a new window/dialog,
@ -396,12 +396,12 @@ namespace MWInput
void InputManager::adjustMouseRegion(int width, int height)
{
mInputCtrl->adjustMouseRegion(width, height);
mInputBinder->adjustMouseRegion(width, height);
}
bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
{
mInputCtrl->keyPressed (arg);
mInputBinder->keyPressed (arg);
unsigned int text = arg.keysym.unicode;
//TODO: Check if we need this with SDL
@ -414,23 +414,27 @@ namespace MWInput
#endif
*/
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text);
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text);
return true;
}
bool InputManager::keyReleased(const SDL_KeyboardEvent &arg )
{
mInputCtrl->keyReleased (arg);
mInputBinder->keyReleased (arg);
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.keysym.sym));
MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc));
return true;
}
bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id )
{
mInputCtrl->mousePressed (arg, id);
mInputBinder->mousePressed (arg, id);
MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id));
@ -448,16 +452,16 @@ namespace MWInput
bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id )
{
mInputCtrl->mouseReleased (arg, id);
mInputBinder->mouseReleased (arg, id);
MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id));
return true;
}
bool InputManager::mouseMoved( const ICS::MWSDLMouseMotionEvent &arg )
bool InputManager::mouseMoved(const SFO::MouseMotionEvent &arg )
{
mInputCtrl->mouseMoved (arg);
mInputBinder->mouseMoved (arg);
resetIdleTime ();
@ -683,7 +687,7 @@ namespace MWInput
bool InputManager::actionIsActive (int id)
{
return mInputCtrl->getChannel (id)->getValue () == 1;
return mInputBinder->getChannel (id)->getValue () == 1;
}
void InputManager::loadKeyDefaults (bool force)
@ -728,29 +732,29 @@ namespace MWInput
for (int i = 0; i < A_Last; ++i)
{
ICS::Control* control;
bool controlExists = mInputCtrl->getChannel(i)->getControlsCount () != 0;
bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0;
if (!controlExists)
{
control = new ICS::Control(boost::lexical_cast<std::string>(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX);
mInputCtrl->addControl(control);
control->attachChannel(mInputCtrl->getChannel(i), ICS::Channel::DIRECT);
mInputBinder->addControl(control);
control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT);
}
else
{
control = mInputCtrl->getChannel(i)->getAttachedControls ().front().control;
control = mInputBinder->getChannel(i)->getAttachedControls ().front().control;
}
if (!controlExists || force ||
( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN
&& mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN
&& mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
))
{
clearAllBindings (control);
if (defaultKeyBindings.find(i) != defaultKeyBindings.end())
mInputCtrl->addKeyBinding(control, static_cast<SDL_Keycode>(defaultKeyBindings[i]), ICS::Control::INCREASE);
mInputBinder->addKeyBinding(control, static_cast<SDL_Keycode>(defaultKeyBindings[i]), ICS::Control::INCREASE);
else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end())
mInputCtrl->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
}
}
}
@ -794,15 +798,15 @@ namespace MWInput
std::string InputManager::getActionBindingName (int action)
{
if (mInputCtrl->getChannel (action)->getControlsCount () == 0)
if (mInputBinder->getChannel (action)->getControlsCount () == 0)
return "#{sNone}";
ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN)
return mInputCtrl->keyCodeToString (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE));
else if (mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
return "#{sMouse} " + boost::lexical_cast<std::string>(mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE));
if (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN)
return mInputBinder->keyCodeToString (mInputBinder->getKeyBinding (c, ICS::Control::INCREASE));
else if (mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
return "#{sMouse} " + boost::lexical_cast<std::string>(mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE));
else
return "#{sNone}";
}
@ -842,9 +846,9 @@ namespace MWInput
void InputManager::enableDetectingBindingMode (int action)
{
ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control;
ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
mInputCtrl->enableDetectingBindingState (c, ICS::Control::INCREASE);
mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE);
}
void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
@ -905,10 +909,10 @@ namespace MWInput
void InputManager::clearAllBindings (ICS::Control* control)
{
// right now we don't really need multiple bindings for the same action, so remove all others first
if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN)
mInputCtrl->removeKeyBinding (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE));
if (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
mInputCtrl->removeMouseButtonBinding (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE));
if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN)
mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE));
if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE));
/// \todo add joysticks here once they are added
}

@ -6,7 +6,7 @@
#include <components/settings/settings.hpp>
#include "../mwbase/inputmanager.hpp"
#include "sdlinputwrapper.hpp"
#include <extern/sdl4ogre/sdlinputwrapper.hpp>
namespace OEngine
{
@ -43,7 +43,6 @@ namespace MyGUI
#include <extern/oics/ICSChannelListener.h>
#include <extern/oics/ICSInputControlSystem.h>
#include <extern/oics/OISCompat.h>
namespace MWInput
{
@ -53,9 +52,9 @@ namespace MWInput
*/
class InputManager :
public MWBase::InputManager,
public ICS::MWSDLKeyListener,
public ICS::MWSDLMouseListener,
public ICS::MWSDLWindowListener,
public SFO::KeyListener,
public SFO::MouseListener,
public SFO::WindowListener,
public ICS::ChannelListener,
public ICS::DetectingBindingListener
{
@ -93,7 +92,7 @@ namespace MWInput
virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg );
virtual bool mouseMoved( const SFO::MouseMotionEvent &arg );
virtual bool windowVisibilityChange( bool visible );
virtual bool windowFocusChange( bool have_focus );
@ -129,10 +128,10 @@ namespace MWInput
MWBase::WindowManager &mWindows;
OMW::Engine& mEngine;
ICS::InputControlSystem* mInputCtrl;
ICS::InputControlSystem* mInputBinder;
MWSDLInputWrapper* mInputManager;
SFO::InputWrapper* mInputManager;
std::string mUserFile;

@ -1,254 +0,0 @@
#include "sdlinputwrapper.hpp"
#include <SDL2/SDL.h>
#include <SDL2/SDL_syswm.h>
#include <OgrePlatform.h>
#include <OgreRoot.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xos.h>
#endif
namespace MWInput
{
MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) :
mWindow(window),
mSDLWindow(NULL),
mWarpCompensate(false),
mMouseRelative(false),
mGrabPointer(false),
mWrapPointer(false)
{
_start();
}
MWSDLInputWrapper::~MWSDLInputWrapper()
{
if(mSDLWindow != NULL)
SDL_DestroyWindow(mSDLWindow);
mSDLWindow = NULL;
SDL_StopTextInput();
SDL_Quit();
}
bool MWSDLInputWrapper::_start()
{
Uint32 flags = SDL_INIT_VIDEO;
if(SDL_WasInit(flags) == 0)
{
//get the HWND from ogre's renderwindow
size_t windowHnd;
mWindow->getCustomAttribute("WINDOW", &windowHnd);
//kindly ask SDL not to trash our OGL context
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
if(SDL_Init(SDL_INIT_VIDEO) != 0)
return false;
//wrap our own event handler around ogre's
mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd);
if(mSDLWindow == NULL)
return false;
SDL_StartTextInput();
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//linux-specific event-handling fixups
SDL_SysWMinfo wm_info;
SDL_VERSION(&wm_info.version);
if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info))
{
Display* display = wm_info.info.x11.display;
Window w = wm_info.info.x11.window;
// Set the input hints so we get keyboard input
XWMHints *wmhints = XAllocWMHints();
if (wmhints) {
wmhints->input = True;
wmhints->flags = InputHint;
XSetWMHints(display, w, wmhints);
XFree(wmhints);
}
//make sure to subscribe to XLib's events
XSelectInput(display, w,
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
ExposureMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | KeyPressMask | KeyReleaseMask |
PropertyChangeMask | StructureNotifyMask |
KeymapStateMask));
XFlush(display);
}
#endif
SDL_ShowCursor(SDL_FALSE);
}
return true;
}
void MWSDLInputWrapper::capture()
{
if(!_start())
throw std::runtime_error(SDL_GetError());
SDL_Event evt;
while(SDL_PollEvent(&evt))
{
switch(evt.type)
{
case SDL_MOUSEMOTION:
//ignore this if it happened due to a warp
if(!_handleWarpMotion(evt.motion))
{
mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion));
//try to keep the mouse inside the window
_wrapMousePointer(evt.motion);
}
break;
case SDL_MOUSEWHEEL:
mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel));
break;
case SDL_MOUSEBUTTONDOWN:
mMouseListener->mousePressed(evt.button, evt.button.button);
break;
case SDL_MOUSEBUTTONUP:
mMouseListener->mouseReleased(evt.button, evt.button.button);
break;
case SDL_KEYDOWN:
_handleKeyPress(evt.key);
break;
case SDL_KEYUP:
mKeyboardListener->keyReleased(evt.key);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
mWindowListener->windowFocusChange(true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
mWindowListener->windowFocusChange(false);
break;
case SDL_WINDOWEVENT_EXPOSED:
mWindowListener->windowVisibilityChange(true);
break;
case SDL_WINDOWEVENT_HIDDEN:
mWindowListener->windowVisibilityChange(false);
break;
//SDL traps ^C signals, pass it to OGRE.
case SDL_QUIT:
Ogre::Root::getSingleton().queueEndRendering();
break;
}
}
}
bool MWSDLInputWrapper::isModifierHeld(int mod)
{
return SDL_GetModState() & mod;
}
void MWSDLInputWrapper::warpMouse(int x, int y)
{
SDL_WarpMouseInWindow(mSDLWindow, x, y);
mWarpCompensate = true;
mWarpX = x;
mWarpY = y;
}
void MWSDLInputWrapper::setGrabPointer(bool grab)
{
SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE;
mGrabPointer = grab;
SDL_SetWindowGrab(mSDLWindow, sdlGrab);
}
void MWSDLInputWrapper::setMouseRelative(bool relative)
{
if(mMouseRelative == relative)
return;
mMouseRelative = relative;
mWrapPointer = false;
//eep, wrap the pointer manually if the input driver doesn't support
//relative positioning natively
if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1)
{
if(relative)
mWrapPointer = true;
}
//now remove all mouse events using the old setting from the queue
SDL_PumpEvents();
SDL_Event dummy[20];
SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
}
bool MWSDLInputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
{
if(!mWarpCompensate)
return false;
//this was a warp event, signal the caller to eat it.
if(evt.x == mWarpX && evt.y == mWarpY)
{
mWarpCompensate = false;
return true;
}
return false;
}
void MWSDLInputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
{
//don't wrap if we don't want relative movements, support relative
//movements natively, or aren't grabbing anyways
if(!mMouseRelative || !mWrapPointer || !mGrabPointer)
return;
int width = 0;
int height = 0;
SDL_GetWindowSize(mSDLWindow, &width, &height);
const int FUDGE_FACTOR_X = width / 4;
const int FUDGE_FACTOR_Y = height / 4;
//warp the mouse if it's about to go outside the window
if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width
|| evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height)
{
warpMouse(width / 2, height / 2);
}
}
void MWSDLInputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt)
{
//SDL keyboard events are followed by the actual text those keys would generate
//to account for languages that require multiple keystrokes to produce a key.
//Look for an event immediately following ours, assuming each key produces exactly
//one character.
//TODO: This won't work for multibyte characters, but MyGUI is the only consumer
//of these, does it even support multibyte characters?
SDL_Event text_evts[1];
if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0)
{
evt.keysym.unicode = text_evts[0].text.text[0];
}
mKeyboardListener->keyPressed(evt);
}
}

@ -1,53 +0,0 @@
#ifndef _MWINPUT_SDLINPUTWRAPPER_H
#define _MWINPUT_SDLINPUTWRAPPER_H
#include "SDL2/SDL_events.h"
#include <extern/oics/OISCompat.h>
#include <OGRE/OgreRenderWindow.h>
namespace MWInput
{
class MWSDLInputWrapper
{
public:
MWSDLInputWrapper(Ogre::RenderWindow* window);
~MWSDLInputWrapper();
void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; }
void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; }
void setWindowEventCallback(ICS::MWSDLWindowListener* listen) { mWindowListener = listen; }
void capture();
bool isModifierHeld(int mod);
void setMouseRelative(bool relative);
bool getMouseRelative() { return mMouseRelative; }
void setGrabPointer(bool grab);
void warpMouse(int x, int y);
private:
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
void _handleKeyPress(SDL_KeyboardEvent& evt);
bool _start();
ICS::MWSDLMouseListener* mMouseListener;
ICS::MWSDLKeyListener* mKeyboardListener;
ICS::MWSDLWindowListener* mWindowListener;
Uint16 mWarpX;
Uint16 mWarpY;
bool mWarpCompensate;
bool mMouseRelative;
bool mWrapPointer;
bool mGrabPointer;
Ogre::RenderWindow* mWindow;
SDL_Window* mSDLWindow;
};
}
#endif

@ -9,7 +9,6 @@ set(OICS_SOURCE_FILES
ICSInputControlSystem_keyboard.cpp
ICSInputControlSystem_mouse.cpp
ICSInputControlSystem_joystick.cpp
OISCompat.h
tinyxml.cpp
tinyxmlparser.cpp
tinyxmlerror.cpp

@ -32,7 +32,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "ICSControl.h"
#include "ICSChannel.h"
#include "OISCompat.h"
#include "../sdl4ogre/events.h"
#define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() );
#define ICS_MAX_JOYSTICK_AXIS 16
@ -50,9 +50,9 @@ namespace ICS
};
class DllExport InputControlSystem :
public MWSDLMouseListener,
public MWSDLKeyListener,
public MWSDLJoyStickListener
public SFO::MouseListener,
public SFO::KeyListener,
public SFO::JoyListener
{
public:
@ -102,7 +102,7 @@ namespace ICS
JoystickIDList& getJoystickIdList(){ return mJoystickIDList; };
// MouseListener
bool mouseMoved(const MWSDLMouseMotionEvent &evt);
bool mouseMoved(const SFO::MouseMotionEvent &evt);
bool mousePressed(const SDL_MouseButtonEvent &evt, Uint8);
bool mouseReleased(const SDL_MouseButtonEvent &evt, Uint8);

@ -219,7 +219,7 @@ namespace ICS
}
// mouse Listeners
bool InputControlSystem::mouseMoved(const MWSDLMouseMotionEvent& evt)
bool InputControlSystem::mouseMoved(const SFO::MouseMotionEvent& evt)
{
if(mActive)
{

@ -0,0 +1,14 @@
set(SDL4OGRE_LIBRARY "sdl4ogre")
# Sources
set(SDL4OGRE_SOURCE_FILES
sdlinputwrapper.cpp
)
add_library(${SDL4OGRE_LIBRARY} STATIC ${SDL4OGRE_SOURCE_FILES})
link_directories(${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(${SDL4OGRE_LIBRARY} ${SDL2_LIBRARY})

@ -0,0 +1,159 @@
#ifndef _OIS_SDL_COMPAT_H
#define _OIS_SDL_COMPAT_H
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_types.h>
namespace OIS
{
//! Keyboard scan codes
enum KeyCode
{
KC_UNASSIGNED = 0x00,
KC_ESCAPE = 0x01,
KC_1 = 0x02,
KC_2 = 0x03,
KC_3 = 0x04,
KC_4 = 0x05,
KC_5 = 0x06,
KC_6 = 0x07,
KC_7 = 0x08,
KC_8 = 0x09,
KC_9 = 0x0A,
KC_0 = 0x0B,
KC_MINUS = 0x0C, // - on main keyboard
KC_EQUALS = 0x0D,
KC_BACK = 0x0E, // backspace
KC_TAB = 0x0F,
KC_Q = 0x10,
KC_W = 0x11,
KC_E = 0x12,
KC_R = 0x13,
KC_T = 0x14,
KC_Y = 0x15,
KC_U = 0x16,
KC_I = 0x17,
KC_O = 0x18,
KC_P = 0x19,
KC_LBRACKET = 0x1A,
KC_RBRACKET = 0x1B,
KC_RETURN = 0x1C, // Enter on main keyboard
KC_LCONTROL = 0x1D,
KC_A = 0x1E,
KC_S = 0x1F,
KC_D = 0x20,
KC_F = 0x21,
KC_G = 0x22,
KC_H = 0x23,
KC_J = 0x24,
KC_K = 0x25,
KC_L = 0x26,
KC_SEMICOLON = 0x27,
KC_APOSTROPHE = 0x28,
KC_GRAVE = 0x29, // accent
KC_LSHIFT = 0x2A,
KC_BACKSLASH = 0x2B,
KC_Z = 0x2C,
KC_X = 0x2D,
KC_C = 0x2E,
KC_V = 0x2F,
KC_B = 0x30,
KC_N = 0x31,
KC_M = 0x32,
KC_COMMA = 0x33,
KC_PERIOD = 0x34, // . on main keyboard
KC_SLASH = 0x35, // / on main keyboard
KC_RSHIFT = 0x36,
KC_MULTIPLY = 0x37, // * on numeric keypad
KC_LMENU = 0x38, // left Alt
KC_SPACE = 0x39,
KC_CAPITAL = 0x3A,
KC_F1 = 0x3B,
KC_F2 = 0x3C,
KC_F3 = 0x3D,
KC_F4 = 0x3E,
KC_F5 = 0x3F,
KC_F6 = 0x40,
KC_F7 = 0x41,
KC_F8 = 0x42,
KC_F9 = 0x43,
KC_F10 = 0x44,
KC_NUMLOCK = 0x45,
KC_SCROLL = 0x46, // Scroll Lock
KC_NUMPAD7 = 0x47,
KC_NUMPAD8 = 0x48,
KC_NUMPAD9 = 0x49,
KC_SUBTRACT = 0x4A, // - on numeric keypad
KC_NUMPAD4 = 0x4B,
KC_NUMPAD5 = 0x4C,
KC_NUMPAD6 = 0x4D,
KC_ADD = 0x4E, // + on numeric keypad
KC_NUMPAD1 = 0x4F,
KC_NUMPAD2 = 0x50,
KC_NUMPAD3 = 0x51,
KC_NUMPAD0 = 0x52,
KC_DECIMAL = 0x53, // . on numeric keypad
KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards
KC_F11 = 0x57,
KC_F12 = 0x58,
KC_F13 = 0x64, // (NEC PC98)
KC_F14 = 0x65, // (NEC PC98)
KC_F15 = 0x66, // (NEC PC98)
KC_KANA = 0x70, // (Japanese keyboard)
KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards
KC_CONVERT = 0x79, // (Japanese keyboard)
KC_NOCONVERT = 0x7B, // (Japanese keyboard)
KC_YEN = 0x7D, // (Japanese keyboard)
KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards
KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98)
KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
KC_AT = 0x91, // (NEC PC98)
KC_COLON = 0x92, // (NEC PC98)
KC_UNDERLINE = 0x93, // (NEC PC98)
KC_KANJI = 0x94, // (Japanese keyboard)
KC_STOP = 0x95, // (NEC PC98)
KC_AX = 0x96, // (Japan AX)
KC_UNLABELED = 0x97, // (J3100)
KC_NEXTTRACK = 0x99, // Next Track
KC_NUMPADENTER = 0x9C, // Enter on numeric keypad
KC_RCONTROL = 0x9D,
KC_MUTE = 0xA0, // Mute
KC_CALCULATOR = 0xA1, // Calculator
KC_PLAYPAUSE = 0xA2, // Play / Pause
KC_MEDIASTOP = 0xA4, // Media Stop
KC_VOLUMEDOWN = 0xAE, // Volume -
KC_VOLUMEUP = 0xB0, // Volume +
KC_WEBHOME = 0xB2, // Web home
KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98)
KC_DIVIDE = 0xB5, // / on numeric keypad
KC_SYSRQ = 0xB7,
KC_RMENU = 0xB8, // right Alt
KC_PAUSE = 0xC5, // Pause
KC_HOME = 0xC7, // Home on arrow keypad
KC_UP = 0xC8, // UpArrow on arrow keypad
KC_PGUP = 0xC9, // PgUp on arrow keypad
KC_LEFT = 0xCB, // LeftArrow on arrow keypad
KC_RIGHT = 0xCD, // RightArrow on arrow keypad
KC_END = 0xCF, // End on arrow keypad
KC_DOWN = 0xD0, // DownArrow on arrow keypad
KC_PGDOWN = 0xD1, // PgDn on arrow keypad
KC_INSERT = 0xD2, // Insert on arrow keypad
KC_DELETE = 0xD3, // Delete on arrow keypad
KC_LWIN = 0xDB, // Left Windows key
KC_RWIN = 0xDC, // Right Windows key
KC_APPS = 0xDD, // AppMenu key
KC_POWER = 0xDE, // System Power
KC_SLEEP = 0xDF, // System Sleep
KC_WAKE = 0xE3, // System Wake
KC_WEBSEARCH = 0xE5, // Web Search
KC_WEBFAVORITES= 0xE6, // Web Favorites
KC_WEBREFRESH = 0xE7, // Web Refresh
KC_WEBSTOP = 0xE8, // Web Stop
KC_WEBFORWARD = 0xE9, // Web Forward
KC_WEBBACK = 0xEA, // Web Back
KC_MYCOMPUTER = 0xEB, // My Computer
KC_MAIL = 0xEC, // Mail
KC_MEDIASELECT = 0xED // Media Select
};
}
#endif

@ -1,53 +1,20 @@
#ifndef _OIS_SDL_COMPAT_H
#define _OIS_SDL_COMPAT_H
#ifndef _SFO_EVENTS_H
#define _SFO_EVENTS_H
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_types.h>
#include <SDL2/SDL.h>
//TODO: Remove this. Right now we want to remain as close to OIS as possible
//So we can easily test the SDL backend
////////////
// Events //
////////////
namespace ICS {
namespace SFO {
/** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */
struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent {
Sint16 zrel;
MWSDLMouseMotionEvent()
{
_init();
}
MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt)
{
_init();
x = evt.x;
y = evt.y;
xrel = evt.xrel;
yrel = evt.yrel;
state = evt.state;
}
MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt)
{
_init();
zrel = evt.y;
}
void _init()
{
x = 0;
y = 0;
xrel = 0;
yrel = 0;
state = 0;
zrel = 0;
}
struct MouseMotionEvent : SDL_MouseMotionEvent {
Sint32 zrel;
Sint32 z;
};
@ -55,27 +22,27 @@ struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent {
// Listeners //
///////////////
class MWSDLMouseListener
class MouseListener
{
public:
virtual ~MWSDLMouseListener() {}
virtual bool mouseMoved( const MWSDLMouseMotionEvent &arg ) = 0;
virtual ~MouseListener() {}
virtual bool mouseMoved( const MouseMotionEvent &arg ) = 0;
virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0;
};
class MWSDLKeyListener
class KeyListener
{
public:
virtual ~MWSDLKeyListener() {}
virtual ~KeyListener() {}
virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0;
virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0;
};
class MWSDLJoyStickListener
class JoyListener
{
public:
virtual ~MWSDLJoyStickListener() {}
virtual ~JoyListener() {}
/** @remarks Joystick button down event */
virtual bool buttonPressed( const SDL_JoyButtonEvent &evt, int button ) = 0;
@ -91,10 +58,10 @@ public:
virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;}
};
class MWSDLWindowListener
class WindowListener
{
public:
virtual ~MWSDLWindowListener() {}
virtual ~WindowListener() {}
/** @remarks The window's visibility changed */
virtual bool windowVisibilityChange( bool visible ) = 0;
@ -104,4 +71,5 @@ public:
};
}
#endif

@ -0,0 +1,420 @@
#include "sdlinputwrapper.hpp"
#include <SDL2/SDL_syswm.h>
#include <OgrePlatform.h>
#include <OgreRoot.h>
#include <boost/locale.hpp>
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
# include <X11/Xlib.h>
# include <X11/Xutil.h>
# include <X11/Xos.h>
#endif
namespace SFO
{
InputWrapper::InputWrapper(Ogre::RenderWindow *window) :
mWindow(window),
mSDLWindow(NULL),
mWarpCompensate(false),
mMouseRelative(false),
mGrabPointer(false),
mWrapPointer(false),
mMouseZ(0),
mMouseY(0),
mMouseX(0)
{
_start();
_setupOISKeys();
}
InputWrapper::~InputWrapper()
{
if(mSDLWindow != NULL)
SDL_DestroyWindow(mSDLWindow);
mSDLWindow = NULL;
SDL_StopTextInput();
SDL_Quit();
}
bool InputWrapper::_start()
{
Uint32 flags = SDL_INIT_VIDEO;
if(SDL_WasInit(flags) == 0)
{
//get the HWND from ogre's renderwindow
size_t windowHnd;
mWindow->getCustomAttribute("WINDOW", &windowHnd);
//kindly ask SDL not to trash our OGL context
//might this be related to http://bugzilla.libsdl.org/show_bug.cgi?id=748 ?
SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software");
if(SDL_Init(SDL_INIT_VIDEO) != 0)
return false;
//wrap our own event handler around ogre's
mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd);
if(mSDLWindow == NULL)
return false;
SDL_StartTextInput();
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
//linux-specific event-handling fixups
//see http://bugzilla.libsdl.org/show_bug.cgi?id=730
SDL_SysWMinfo wm_info;
SDL_VERSION(&wm_info.version);
if(SDL_GetWindowWMInfo(mSDLWindow,&wm_info))
{
Display* display = wm_info.info.x11.display;
Window w = wm_info.info.x11.window;
// Set the input hints so we get keyboard input
XWMHints *wmhints = XAllocWMHints();
if (wmhints) {
wmhints->input = True;
wmhints->flags = InputHint;
XSetWMHints(display, w, wmhints);
XFree(wmhints);
}
//make sure to subscribe to XLib's events
XSelectInput(display, w,
(FocusChangeMask | EnterWindowMask | LeaveWindowMask |
ExposureMask | ButtonPressMask | ButtonReleaseMask |
PointerMotionMask | KeyPressMask | KeyReleaseMask |
PropertyChangeMask | StructureNotifyMask |
KeymapStateMask));
XFlush(display);
}
#endif
SDL_ShowCursor(SDL_FALSE);
}
return true;
}
void InputWrapper::capture()
{
if(!_start())
throw std::runtime_error(SDL_GetError());
SDL_Event evt;
while(SDL_PollEvent(&evt))
{
switch(evt.type)
{
case SDL_MOUSEMOTION:
//ignore this if it happened due to a warp
if(!_handleWarpMotion(evt.motion))
{
mMouseListener->mouseMoved(_packageMouseMotion(evt));
//try to keep the mouse inside the window
_wrapMousePointer(evt.motion);
}
break;
case SDL_MOUSEWHEEL:
mMouseListener->mouseMoved(_packageMouseMotion(evt));
break;
case SDL_MOUSEBUTTONDOWN:
mMouseListener->mousePressed(evt.button, evt.button.button);
break;
case SDL_MOUSEBUTTONUP:
mMouseListener->mouseReleased(evt.button, evt.button.button);
break;
case SDL_KEYDOWN:
_handleKeyPress(evt.key);
break;
case SDL_KEYUP:
mKeyboardListener->keyReleased(evt.key);
break;
case SDL_WINDOWEVENT_FOCUS_GAINED:
mWindowListener->windowFocusChange(true);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
mWindowListener->windowFocusChange(false);
break;
case SDL_WINDOWEVENT_EXPOSED:
mWindowListener->windowVisibilityChange(true);
break;
case SDL_WINDOWEVENT_HIDDEN:
mWindowListener->windowVisibilityChange(false);
break;
//SDL traps ^C signals, pass it to OGRE.
case SDL_QUIT:
Ogre::Root::getSingleton().queueEndRendering();
break;
}
}
}
bool InputWrapper::isModifierHeld(int mod)
{
return SDL_GetModState() & mod;
}
void InputWrapper::warpMouse(int x, int y)
{
SDL_WarpMouseInWindow(mSDLWindow, x, y);
mWarpCompensate = true;
mWarpX = x;
mWarpY = y;
}
void InputWrapper::setGrabPointer(bool grab)
{
SDL_bool sdlGrab = grab ? SDL_TRUE : SDL_FALSE;
mGrabPointer = grab;
SDL_SetWindowGrab(mSDLWindow, sdlGrab);
}
void InputWrapper::setMouseRelative(bool relative)
{
if(mMouseRelative == relative)
return;
mMouseRelative = relative;
mWrapPointer = false;
//eep, wrap the pointer manually if the input driver doesn't support
//relative positioning natively
if(SDL_SetRelativeMouseMode(relative ? SDL_TRUE : SDL_FALSE) == -1)
{
if(relative)
mWrapPointer = true;
}
//now remove all mouse events using the old setting from the queue
SDL_PumpEvents();
SDL_Event dummy[20];
SDL_PeepEvents(dummy, 20, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION);
}
bool InputWrapper::_handleWarpMotion(const SDL_MouseMotionEvent& evt)
{
if(!mWarpCompensate)
return false;
//this was a warp event, signal the caller to eat it.
if(evt.x == mWarpX && evt.y == mWarpY)
{
mWarpCompensate = false;
return true;
}
return false;
}
void InputWrapper::_wrapMousePointer(const SDL_MouseMotionEvent& evt)
{
//don't wrap if we don't want relative movements, support relative
//movements natively, or aren't grabbing anyways
if(!mMouseRelative || !mWrapPointer || !mGrabPointer)
return;
int width = 0;
int height = 0;
SDL_GetWindowSize(mSDLWindow, &width, &height);
const int FUDGE_FACTOR_X = width / 4;
const int FUDGE_FACTOR_Y = height / 4;
//warp the mouse if it's about to go outside the window
if(evt.x - FUDGE_FACTOR_X < 0 || evt.x + FUDGE_FACTOR_X > width
|| evt.y - FUDGE_FACTOR_Y < 0 || evt.y + FUDGE_FACTOR_Y > height)
{
warpMouse(width / 2, height / 2);
}
}
void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt)
{
//SDL keyboard events are followed by the actual text those keys would generate
//to account for languages that require multiple keystrokes to produce a key.
//Look for an event immediately following ours, assuming each key produces exactly
//one character or none at all.
//TODO: Check if this works properly for multibyte symbols
//do we have to worry about endian-ness?
//for that matter, check if we even need to do any of this.
SDL_Event text_evts[1];
if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0)
{
const char* symbol = text_evts[0].text.text;
Uint32 num_bytes = strlen(symbol);
//no valid character is more than 4 bytes
if(num_bytes > 0 && num_bytes <= 4)
{
Uint32 u32_symbol = boost::locale::conv::utf_to_utf<Uint32>(symbol)[0];
evt.keysym.unicode = u32_symbol;
}
}
mKeyboardListener->keyPressed(evt);
}
MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt)
{
MouseMotionEvent pack_evt;
pack_evt.x = mMouseX;
pack_evt.xrel = 0;
pack_evt.y = mMouseY;
pack_evt.yrel = 0;
pack_evt.z = mMouseZ;
pack_evt.zrel = 0;
if(evt.type == SDL_MOUSEMOTION)
{
pack_evt.x = mMouseX = evt.motion.x;
pack_evt.y = mMouseY = evt.motion.y;
pack_evt.xrel = evt.motion.xrel;
pack_evt.yrel = evt.motion.yrel;
}
else if(evt.type == SDL_MOUSEWHEEL)
{
mMouseZ += pack_evt.zrel = evt.wheel.y;
pack_evt.z = mMouseZ;
}
else
{
throw new std::runtime_error("Tried to package non-motion event!");
}
return pack_evt;
}
OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code)
{
OIS::KeyCode kc = OIS::KC_UNASSIGNED;
KeyMap::const_iterator ois_equiv = mKeyMap.find(code);
if(ois_equiv != mKeyMap.end())
kc = ois_equiv->second;
return kc;
}
void InputWrapper::_setupOISKeys()
{
//lifted from OIS's SDLKeyboard.cpp
mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED));
mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) );
mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) );
mKeyMap.insert( KeyMap::value_type(SDLK_2, OIS::KC_2) );
mKeyMap.insert( KeyMap::value_type(SDLK_3, OIS::KC_3) );
mKeyMap.insert( KeyMap::value_type(SDLK_4, OIS::KC_4) );
mKeyMap.insert( KeyMap::value_type(SDLK_5, OIS::KC_5) );
mKeyMap.insert( KeyMap::value_type(SDLK_6, OIS::KC_6) );
mKeyMap.insert( KeyMap::value_type(SDLK_7, OIS::KC_7) );
mKeyMap.insert( KeyMap::value_type(SDLK_8, OIS::KC_8) );
mKeyMap.insert( KeyMap::value_type(SDLK_9, OIS::KC_9) );
mKeyMap.insert( KeyMap::value_type(SDLK_0, OIS::KC_0) );
mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, OIS::KC_MINUS) );
mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, OIS::KC_EQUALS) );
mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, OIS::KC_BACK) );
mKeyMap.insert( KeyMap::value_type(SDLK_TAB, OIS::KC_TAB) );
mKeyMap.insert( KeyMap::value_type(SDLK_q, OIS::KC_Q) );
mKeyMap.insert( KeyMap::value_type(SDLK_w, OIS::KC_W) );
mKeyMap.insert( KeyMap::value_type(SDLK_e, OIS::KC_E) );
mKeyMap.insert( KeyMap::value_type(SDLK_r, OIS::KC_R) );
mKeyMap.insert( KeyMap::value_type(SDLK_t, OIS::KC_T) );
mKeyMap.insert( KeyMap::value_type(SDLK_y, OIS::KC_Y) );
mKeyMap.insert( KeyMap::value_type(SDLK_u, OIS::KC_U) );
mKeyMap.insert( KeyMap::value_type(SDLK_i, OIS::KC_I) );
mKeyMap.insert( KeyMap::value_type(SDLK_o, OIS::KC_O) );
mKeyMap.insert( KeyMap::value_type(SDLK_p, OIS::KC_P) );
mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, OIS::KC_RETURN) );
mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LCONTROL));
mKeyMap.insert( KeyMap::value_type(SDLK_a, OIS::KC_A) );
mKeyMap.insert( KeyMap::value_type(SDLK_s, OIS::KC_S) );
mKeyMap.insert( KeyMap::value_type(SDLK_d, OIS::KC_D) );
mKeyMap.insert( KeyMap::value_type(SDLK_f, OIS::KC_F) );
mKeyMap.insert( KeyMap::value_type(SDLK_g, OIS::KC_G) );
mKeyMap.insert( KeyMap::value_type(SDLK_h, OIS::KC_H) );
mKeyMap.insert( KeyMap::value_type(SDLK_j, OIS::KC_J) );
mKeyMap.insert( KeyMap::value_type(SDLK_k, OIS::KC_K) );
mKeyMap.insert( KeyMap::value_type(SDLK_l, OIS::KC_L) );
mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, OIS::KC_SEMICOLON) );
mKeyMap.insert( KeyMap::value_type(SDLK_COLON, OIS::KC_COLON) );
mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, OIS::KC_APOSTROPHE) );
mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, OIS::KC_GRAVE) );
mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, OIS::KC_LSHIFT) );
mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, OIS::KC_BACKSLASH) );
mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, OIS::KC_SLASH) );
mKeyMap.insert( KeyMap::value_type(SDLK_z, OIS::KC_Z) );
mKeyMap.insert( KeyMap::value_type(SDLK_x, OIS::KC_X) );
mKeyMap.insert( KeyMap::value_type(SDLK_c, OIS::KC_C) );
mKeyMap.insert( KeyMap::value_type(SDLK_v, OIS::KC_V) );
mKeyMap.insert( KeyMap::value_type(SDLK_b, OIS::KC_B) );
mKeyMap.insert( KeyMap::value_type(SDLK_n, OIS::KC_N) );
mKeyMap.insert( KeyMap::value_type(SDLK_m, OIS::KC_M) );
mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, OIS::KC_COMMA) );
mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, OIS::KC_PERIOD));
mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, OIS::KC_RSHIFT));
mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, OIS::KC_MULTIPLY) );
mKeyMap.insert( KeyMap::value_type(SDLK_LALT, OIS::KC_LMENU) );
mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, OIS::KC_SPACE));
mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, OIS::KC_CAPITAL) );
mKeyMap.insert( KeyMap::value_type(SDLK_F1, OIS::KC_F1) );
mKeyMap.insert( KeyMap::value_type(SDLK_F2, OIS::KC_F2) );
mKeyMap.insert( KeyMap::value_type(SDLK_F3, OIS::KC_F3) );
mKeyMap.insert( KeyMap::value_type(SDLK_F4, OIS::KC_F4) );
mKeyMap.insert( KeyMap::value_type(SDLK_F5, OIS::KC_F5) );
mKeyMap.insert( KeyMap::value_type(SDLK_F6, OIS::KC_F6) );
mKeyMap.insert( KeyMap::value_type(SDLK_F7, OIS::KC_F7) );
mKeyMap.insert( KeyMap::value_type(SDLK_F8, OIS::KC_F8) );
mKeyMap.insert( KeyMap::value_type(SDLK_F9, OIS::KC_F9) );
mKeyMap.insert( KeyMap::value_type(SDLK_F10, OIS::KC_F10) );
mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCKCLEAR, OIS::KC_NUMLOCK) );
mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLLOCK, OIS::KC_SCROLL));
mKeyMap.insert( KeyMap::value_type(SDLK_KP_7, OIS::KC_NUMPAD7) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_8, OIS::KC_NUMPAD8) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_9, OIS::KC_NUMPAD9) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, OIS::KC_SUBTRACT) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_4, OIS::KC_NUMPAD4) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_5, OIS::KC_NUMPAD5) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_6, OIS::KC_NUMPAD6) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, OIS::KC_ADD) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_1, OIS::KC_NUMPAD1) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_2, OIS::KC_NUMPAD2) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_3, OIS::KC_NUMPAD3) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_0, OIS::KC_NUMPAD0) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, OIS::KC_DECIMAL) );
mKeyMap.insert( KeyMap::value_type(SDLK_F11, OIS::KC_F11) );
mKeyMap.insert( KeyMap::value_type(SDLK_F12, OIS::KC_F12) );
mKeyMap.insert( KeyMap::value_type(SDLK_F13, OIS::KC_F13) );
mKeyMap.insert( KeyMap::value_type(SDLK_F14, OIS::KC_F14) );
mKeyMap.insert( KeyMap::value_type(SDLK_F15, OIS::KC_F15) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, OIS::KC_NUMPADEQUALS) );
mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, OIS::KC_DIVIDE) );
mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, OIS::KC_SYSRQ) );
mKeyMap.insert( KeyMap::value_type(SDLK_RALT, OIS::KC_RMENU) );
mKeyMap.insert( KeyMap::value_type(SDLK_HOME, OIS::KC_HOME) );
mKeyMap.insert( KeyMap::value_type(SDLK_UP, OIS::KC_UP) );
mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, OIS::KC_PGUP) );
mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, OIS::KC_LEFT) );
mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, OIS::KC_RIGHT) );
mKeyMap.insert( KeyMap::value_type(SDLK_END, OIS::KC_END) );
mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, OIS::KC_DOWN) );
mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, OIS::KC_PGDOWN) );
mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, OIS::KC_INSERT) );
mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, OIS::KC_DELETE) );
}
}

@ -0,0 +1,67 @@
#ifndef _MWINPUT_SDLINPUTWRAPPER_H
#define _MWINPUT_SDLINPUTWRAPPER_H
#include "SDL2/SDL_events.h"
#include <OGRE/OgreRenderWindow.h>
#include <boost/unordered_map.hpp>
#include "OISCompat.h"
#include "events.h"
namespace SFO
{
class InputWrapper
{
public:
InputWrapper(Ogre::RenderWindow* window);
~InputWrapper();
void setMouseEventCallback(MouseListener* listen) { mMouseListener = listen; }
void setKeyboardEventCallback(KeyListener* listen) { mKeyboardListener = listen; }
void setWindowEventCallback(WindowListener* listen) { mWindowListener = listen; }
void capture();
bool isModifierHeld(int mod);
void setMouseRelative(bool relative);
bool getMouseRelative() { return mMouseRelative; }
void setGrabPointer(bool grab);
OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code);
void warpMouse(int x, int y);
private:
bool _handleWarpMotion(const SDL_MouseMotionEvent& evt);
void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
void _handleKeyPress(SDL_KeyboardEvent& evt);
bool _start();
void _setupOISKeys();
SFO::MouseListener* mMouseListener;
SFO::KeyListener* mKeyboardListener;
SFO::WindowListener* mWindowListener;
typedef boost::unordered::unordered_map<SDL_Keycode, OIS::KeyCode> KeyMap;
KeyMap mKeyMap;
Uint16 mWarpX;
Uint16 mWarpY;
bool mWarpCompensate;
bool mMouseRelative;
bool mWrapPointer;
bool mGrabPointer;
Sint32 mMouseZ;
Sint32 mMouseX;
Sint32 mMouseY;
Ogre::RenderWindow* mWindow;
SDL_Window* mSDLWindow;
};
}
#endif
Loading…
Cancel
Save