Anyways I have included a demo to give you an idea as well, everything compiles out of the box. The main reason I made this is for a camera I am making in which I needed timed keys, other than that I am just releasing it in case someone else would like something of the sort as well.
Now for the code. It's all Irrlicht "coding standards" compliant so it should be easy to learn, and it's nothing much but a really small layer. Note that gui message handling, etc., isn't put into here because I didn't need it. If someone else wants to do that, then fell free.
Oh yes, and also pay attention to the method updateAll(). It must be called after key handling for pressed keys to register correctly. If you don't do it, then pressed keys won't register at all.
Also a note on why I made the method updateAll(), it's because of how Irrlicht handles key handling. There is a delay between the first moment the key was pressed, and when Irrlicht repeats the press. So the delay created some discrepancies in the timing, so that's another reason. It was also to fix the getKeyPressed() and getMouseButtonPressed() because people usually check keys in a frame-dependent process which means that the delay, from Irrlicht, would cause pressed keys to be repeated.
Overall it is hard to explain, but believe I tried it already, so just make sure you use updateAll() like in the demo. Anyways, here is the code.
EKeyState.h
Code: Select all
#ifndef __E_KEY_STATE_H_INCLUDED__
#define __E_KEY_STATE_H_INCLUDED__
enum E_KEY_STATE
{
EKS_PRESSED,
EKS_DOWN,
EKS_UP,
EKS_RELEASED
};
#endif // __E_KEY_STATE_H_INCLUDED__
Code: Select all
#ifndef __E_MOUSE_BUTTON_H_INCLUDED__
#define __E_MOUSE_BUTTON_H_INCLUDED__
enum E_MOUSE_BUTTON
{
EMB_LEFT,
EMB_MIDDLE,
EMB_RIGHT
};
#endif // __E_MOUSE_BUTTON_H_INCLUDED__
Code: Select all
#ifndef __C_TIME_KEY_EVENT_RECEIVER_H_INCLUDED__
#define __C_TIME_KEY_EVENT_RECEIVER_H_INCLUDED__
#include <Irrlicht.h>
#include "EKeyState.h"
#include "EMouseButton.h"
struct SKeyInformation
{
E_KEY_STATE key;
irr::u32 time;
};
class CTimeKeyEventReceiver : public irr::IEventReceiver
{
public:
//! constructor
CTimeKeyEventReceiver(irr::ITimer* timer);
//! destructor
virtual ~CTimeKeyEventReceiver();
//! OnEvent callback
virtual bool OnEvent(const irr::SEvent& event);
//! Tells whether the key is pressed or not
bool getKey(irr::EKEY_CODE key) const;
//! Tells whether the key is pressed once or not
bool getKeyPressed(irr::EKEY_CODE key) const;
//! Tells whether the mouse button is pressed or not
bool getMouseButton(E_MOUSE_BUTTON button) const;
//! Tells whether the mouse button is pressed once or not
bool getMouseButtonPressed(E_MOUSE_BUTTON button) const;
//! Tells how long the key has been pressed
irr::u32 getKeyTime(irr::EKEY_CODE key) const;
//! Tells how long the mouse button has been pressed
irr::u32 getMouseButtonTime(E_MOUSE_BUTTON button) const;
//! Updates all the key states
void updateAll();
private:
inline void pressKeyboardButton(irr::u32 index);
inline void releaseKeyboardButton(irr::u32 index);
inline void pressMouseButton(irr::u32 index);
inline void releaseMouseButton(irr::u32 index);
protected:
irr::ITimer* Timer;
irr::u32 LastTime;
SKeyInformation Keyboard[irr::KEY_KEY_CODES_COUNT];
SKeyInformation Mouse[2];
};
#endif // __C_TIME_KEY_EVENT_RECEIVER_H_INCLUDED_
Code: Select all
#include "CTimeKeyEventReceiver.h"
using namespace irr;
using namespace irr::core;
using namespace irr::io;
using namespace irr::video;
using namespace irr::scene;
using namespace irr::gui;
CTimeKeyEventReceiver::CTimeKeyEventReceiver(ITimer* timer)
: Timer(timer)
{
for (u32 i = 0; i < u32(KEY_KEY_CODES_COUNT); i ++)
{
Keyboard[i].key = EKS_UP;
Keyboard[i].time = 0;
}
Mouse[EMB_LEFT].key = Mouse[EMB_MIDDLE].key = Mouse[EMB_RIGHT].key = EKS_UP;
Mouse[EMB_LEFT].time = Mouse[EMB_MIDDLE].time = Mouse[EMB_RIGHT].time = 0;
LastTime = Timer->getTime();
}
CTimeKeyEventReceiver::~CTimeKeyEventReceiver()
{
}
bool CTimeKeyEventReceiver::OnEvent(const SEvent& event)
{
switch (event.EventType)
{
case EET_KEY_INPUT_EVENT:
{
EKEY_CODE key = event.KeyInput.Key;
if (event.KeyInput.PressedDown)
{
pressKeyboardButton(key);
}
else
{
releaseKeyboardButton(key);
Keyboard[key].time = 0;
}
return true;
} break;
case EET_MOUSE_INPUT_EVENT:
{
switch (event.MouseInput.Event)
{
case EMIE_LMOUSE_LEFT_UP:
releaseMouseButton(EMB_LEFT);
break;
case EMIE_MMOUSE_LEFT_UP:
releaseMouseButton(EMB_MIDDLE);
break;
case EMIE_RMOUSE_LEFT_UP:
releaseMouseButton(EMB_RIGHT);
break;
case EMIE_LMOUSE_PRESSED_DOWN:
pressMouseButton(EMB_LEFT);
break;
case EMIE_MMOUSE_PRESSED_DOWN:
pressMouseButton(EMB_MIDDLE);
break;
case EMIE_RMOUSE_PRESSED_DOWN:
pressMouseButton(EMB_RIGHT);
break;
}
return true;
} break;
}
return false;
}
void CTimeKeyEventReceiver::updateAll()
{
u32 DiffTime = Timer->getTime() - LastTime;
LastTime = Timer->getTime();
for (u32 i = 0; i < u32(KEY_KEY_CODES_COUNT); ++ i)
{
if (Keyboard[i].key == EKS_PRESSED)
Keyboard[i].key = EKS_DOWN;
if (Keyboard[i].key == EKS_RELEASED)
Keyboard[i].key = EKS_UP;
if (Keyboard[i].key == EKS_DOWN)
Keyboard[i].time += DiffTime;
}
for (u32 i = 0; i < 3; ++ i)
{
if (Mouse[i].key == EKS_PRESSED)
Mouse[i].key = EKS_DOWN;
if (Mouse[i].key == EKS_RELEASED)
Mouse[i].key = EKS_UP;
if (Mouse[i].key == EKS_DOWN)
Mouse[i].time += DiffTime;
}
}
bool CTimeKeyEventReceiver::getKey(EKEY_CODE key) const
{
if (Keyboard[key].key == EKS_DOWN)
return true;
return false;
}
bool CTimeKeyEventReceiver::getKeyPressed(EKEY_CODE key) const
{
if (Keyboard[key].key == EKS_PRESSED)
return true;
return false;
}
u32 CTimeKeyEventReceiver::getKeyTime(EKEY_CODE key) const
{
return Keyboard[key].time;
}
bool CTimeKeyEventReceiver::getMouseButton(E_MOUSE_BUTTON button) const
{
if (Mouse[button].key == EKS_DOWN)
return true;
return false;
}
bool CTimeKeyEventReceiver::getMouseButtonPressed(E_MOUSE_BUTTON button) const
{
if (Mouse[button].key == EKS_PRESSED)
return true;
return false;
}
u32 CTimeKeyEventReceiver::getMouseButtonTime(E_MOUSE_BUTTON button)
{
return Mouse[button].time;
}
void CTimeKeyEventReceiver::pressKeyboardButton(u32 index)
{
if (Keyboard[index].key != EKS_DOWN)
Keyboard[index].key = EKS_PRESSED;
}
void CTimeKeyEventReceiver::releaseKeyboardButton(u32 index)
{
if (Keyboard[index].key != EKS_UP)
Keyboard[index].key = EKS_RELEASED;
}
void CTimeKeyEventReceiver::pressMouseButton(u32 index)
{
if (Mouse[index].key != EKS_DOWN)
Mouse[index].key = EKS_PRESSED;
}
void CTimeKeyEventReceiver::releaseMouseButton(u32 index)
{
if (Mouse[index].key != EKS_UP)
Mouse[index].key = EKS_RELEASED;
}
Code: Select all
#include <Irrlicht.h>
#include <iostream>
#include "CTimeKeyEventReceiver.h"
using namespace irr;
using namespace irr::core;
using namespace irr::io;
using namespace irr::video;
using namespace irr::scene;
using namespace irr::gui;
int main()
{
IrrlichtDevice* irrDevice;
E_DRIVER_TYPE driverType;
s32 choice;
std::cout << "Select your driver:\n" << " (1) - OpenGL \n" <<
" (2) - Direct3D9 \n" << std::endl;
std::cin >> choice;
if (choice == 2)
driverType = EDT_DIRECT3D9;
else
driverType = EDT_OPENGL;
irrDevice = createDevice(driverType, dimension2di(640, 480));
IVideoDriver* irrDriver = irrDevice->getVideoDriver();
ISceneManager* irrSceneMgr = irrDevice->getSceneManager();
IGUIEnvironment* irrGUIEnv = irrDevice->getGUIEnvironment();
CTimeKeyEventReceiver* irrEventRecv = new CTimeKeyEventReceiver(irrDevice->getTimer());
irrDevice->setEventReceiver(irrEventRecv);
irrDevice->setWindowCaption(L"CTimeKeyEventReceiver demo");
s32 lastTime = -1, lastTimeM = -1;
while (irrDevice->run())
{
if (irrDevice->isWindowActive())
{
irrDriver->beginScene(true, true, SColor(255,128,128,128));
irrSceneMgr->drawAll();
irrGUIEnv->drawAll();
irrDriver->endScene();
if (irrEventRecv->getKeyPressed(KEY_KEY_S))
{
std::cout << "S was pressed." << std::endl;
}
if (irrEventRecv->getKey(KEY_KEY_A))
{
s32 time = irrEventRecv->getKeyTime(KEY_KEY_A);
if ((lastTime / 1000) != (time / 1000))
{
std::cout << "A key: " << time / 1000 << std::endl;
lastTime = time;
}
}
if (irrEventRecv->getMouseButtonPressed(EMB_RIGHT))
{
std::cout << "Right mouse button was pressed." << std::endl;
}
if (irrEventRecv->getMouseButton(EMB_LEFT))
{
s32 time = irrEventRecv->getMouseButtonTime(EMB_LEFT);
if ((lastTimeM / 1000) != (time / 1000))
{
std::cout << "Left Mouse: " << time / 1000 << std::endl;
lastTimeM = time;
}
}
irrEventRecv->updateAll();
}
}
irrDevice->drop();
delete irrEventRecv;
return 0;
}
