Mast Event Receiver

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
4Clark
Posts: 5
Joined: Fri Feb 25, 2011 9:14 pm
Location: UCMST, MI

Mast Event Receiver

Post by 4Clark »

I am a beginner in C++ but I understand it well once I am introduced to something new. Me and a partner are making a game using Irrlicht and used a mast event receiver we found online. It's not working! Help please, here is the code we copied:
/// ==================================================================================================
/// MastEventReceiver code is © (Copyright) Robert E. Demarest, AKA Mastiff or Mastiff Odit
/// This file may be used in any non-commercial or commercial project as long as the following conditions are met:
/// You may not claim this code as being your own.
/// You may not use this code for any harmful, malicious or otherwise damaging programs.
///
/// This is version 1.2a of the class.
/// This class is designed for use with the Irrlicht Engine, it was written for version 1.3 of the engine.
/// ==================================================================================================

//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// To use this Class just add #include "MastEventReceiver.cpp" to the end of your includes list. (or add the class in-line into your program)
// Then create an instance of it like so: MastEventReceiver eventReceiver;
// Then call the initialization fucntion like so: eventReceiver.init();
// Then inside your Main Game Loop place "eventReceiver.endEventProcess();" in the beginning of your game loop, before anything -
// that would require input, then put "eventReceiver.startEventProcess();" at the very end of your Main Game Loop.
// yeah I know it's confusing, but it makes alot more sense in the internals of the class.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////

// Change this to the path where your Irrlicht Header Files are.
#include <irrlicht.h>

using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

/// ==============================
/// MastEventReceiver
/// ==============================
class MastEventReceiver : public IEventReceiver
{

protected:
// Enumeration for UP, DOWN, PRESSED and RELEASED key states. Also used for mouse button states.
enum keyStatesENUM {UP, DOWN, PRESSED, RELEASED};

// Enumeration for Event Handling State.
enum processStateENUM {STARTED, ENDED};

// Mouse button states.
keyStatesENUM mouseButtonState[2]; //Left(0), Middle(1) and Right(2) Buttons.

// Keyboard key states.
keyStatesENUM keyState[KEY_KEY_CODES_COUNT];

// Mouse X/Y coordinates and Wheel data.
struct mouseData
{
int X;
int Y;
float wheel; //wheel is how far the wheel has moved
};
struct mouseData mouse;

processStateENUM processState; // STARTED = handling events, ENDED = not handling events

virtual bool OnEvent(SEvent event)
{
bool eventprocessed = false;

//////////////////////////////
// Keyboard Input Event
//////////////////////////////
if (event.EventType == EET_KEY_INPUT_EVENT)
{
if (processState == STARTED)
{
// if key is Pressed Down
if (event.KeyInput.PressedDown == true)
{
// If key was not down before
if (keyState[event.KeyInput.Key] != DOWN)
{
keyState[event.KeyInput.Key] = PRESSED; // Set to Pressed
}
else
{
// if key was down before
keyState[event.KeyInput.Key] = DOWN; // Set to Down
}
}
else
{

// if the key is down
if (keyState[event.KeyInput.Key] != UP)
{
keyState[event.KeyInput.Key] = RELEASED; // Set to Released
}
}
}


eventprocessed = true;
}

//////////////////////////////
// Mouse Input Event
//////////////////////////////

if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
if (processState == STARTED)
{
//Mouse changed position
if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
mouse.Y = event.MouseInput.Y;
mouse.X = event.MouseInput.X;
}

//Wheel moved.
if (event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
mouse.wheel += event.MouseInput.Wheel;
}

//Left Mouse Button Pressed
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[0] == UP || mouseButtonState[0] == RELEASED)
{
mouseButtonState[0] = PRESSED;
}
else
{
mouseButtonState[0] = DOWN;
}
}

//Left Mouse Button Rleased
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
//
if (mouseButtonState[0] != UP)
{
mouseButtonState[0] = RELEASED;
}
}

//Middle Mouse Button Pressed
if (event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[1] == UP || mouseButtonState[1] == RELEASED)
{
mouseButtonState[1] = PRESSED;
}
else
{
mouseButtonState[1] = DOWN;
}
}

//Middle Mouse Button Rleased
if (event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP)
{
//
if (mouseButtonState[1] != UP)
{
mouseButtonState[1] = RELEASED;
}
}

//Right Mouse Button Pressed
if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[2] == UP || mouseButtonState[2] == RELEASED)
{
mouseButtonState[2] = PRESSED;
}
else
{
mouseButtonState[2] = DOWN;
}
}

//Right Mouse Button Rleased
if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
{
//
if (mouseButtonState[2] != UP)
{
mouseButtonState[2] = RELEASED;
}
}
}


eventprocessed = true;
}


return eventprocessed;
}


//////////////////////
// Public functions
//////////////////////
public:

float mouseWheel()
{
return mouse.wheel;
}

int mouseX()
{
return mouse.X;
}

int mouseY()
{
return mouse.Y;
}

bool leftMouseReleased()
{
if (mouseButtonState[0] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool leftMouseUp()
{
if (mouseButtonState[0] == RELEASED || mouseButtonState[0] == UP)
{
return true;
}
else
{
return false;
}
}

bool leftMousePressed()
{
if (mouseButtonState[0] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool leftMouseDown()
{
if (mouseButtonState[0] == PRESSED || mouseButtonState[0] == DOWN)
{
return true;
}
else
{
return false;
}
}

bool middleMouseReleased()
{
if (mouseButtonState[1] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool middleMouseUp()
{
if (mouseButtonState[1] == RELEASED || mouseButtonState[1] == UP)
{
return true;
}
else
{
return false;
}
}

bool middleMousePressed()
{
if (mouseButtonState[1] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool middleMouseDown()
{
if (mouseButtonState[1] == PRESSED || mouseButtonState[1] == DOWN)
{
return true;
}
else
{
return false;
}
}

bool rightMouseReleased()
{
if (mouseButtonState[2] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool rightMouseUp()
{
if (mouseButtonState[2] == RELEASED || mouseButtonState[2] == UP)
{
return true;
}
else
{
return false;
}
}

bool rightMousePressed()
{
if (mouseButtonState[2] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool rightMouseDown()
{
if (mouseButtonState[2] == PRESSED || mouseButtonState[2] == DOWN)
{
return true;
}
else
{
return false;
}
}//

bool keyPressed(char keycode)
{
if (keyState[keycode] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool keyDown(char keycode)
{
if (keyState[keycode] == DOWN || keyState[keycode] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool keyUp(char keycode)
{
if (keyState[keycode] == UP || keyState[keycode] == RELEASED)
{
return true;
}
else
{
return false;
}
}

bool keyReleased(char keycode)
{
if (keyState[keycode] == RELEASED)
{
return true;
}
else
{
return false;
}
}


// This is used so that the Key States will not be changed during execution of your Main game loop.
// Place this at the very START of your Main Loop
void endEventProcess()
{
processState = ENDED;
}

// This is used so that the Key States will not be changed during execution of your Main game loop.
// Place this function at the END of your Main Loop.
void startEventProcess()
{

processState = STARTED;
//Keyboard Key States
for (int i = 0; i < KEY_KEY_CODES_COUNT; i++)
{
if (keyState == RELEASED)
{
keyState = UP;
}

if (keyState == PRESSED)
{
keyState = DOWN;
}
}
//Mouse Button States
for (int i = 0; i <= 2; i++)
{
if (mouseButtonState == RELEASED)
{
mouseButtonState = UP;
}

if (mouseButtonState == PRESSED)
{
mouseButtonState = DOWN;
}
}
//Mouse Wheel state
mouse.wheel = 0.0f;

}

void init()
{
//KeyBoard States.
for (int i = 0; i <= KEY_KEY_CODES_COUNT; i++)
{
keyState = UP;
}
//Mouse states
for (int i = 0; i <= 2; i++)
{
mouseButtonState = UP;
}
//Mouse X/Y coordenates.
mouse.X = 0;
mouse.Y = 0;
mouse.wheel = 0.0f;
}


};
/// ==========================================
/// END OF MastEventReceiver
/// ==========================================
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Post by Radikalizm »

'It doesn't work' doesn't really tell us that much...
what are your trying to accomplish? what are the expected results? what doesn't work? does it give any error codes?
4Clark
Posts: 5
Joined: Fri Feb 25, 2011 9:14 pm
Location: UCMST, MI

Post by 4Clark »

It says segmentation fault when we try to run it. We're trying to make a game, it's a first person shooter. We are using the mast event receiver for user input.
Radikalizm
Posts: 1215
Joined: Tue Jan 09, 2007 7:03 pm
Location: Leuven, Belgium

Post by Radikalizm »

When exactly does this segmentation fault occur? Do you have a small code sample to reproduce it?
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

I would like to give you an advice on this, Learn to debug.
Once you know how to debug you'll have almost all of similar problems solved by yourself.
Working on game: Marrbles (Currently stopped).
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Thank you for the advice, I will look into that. I am the original poster's partner. Our issue is that after we call the initialise function, we get a segmentation fault. The initialisation function looks good to me, but I am unsure.

Code: Select all

void init()
   {
      //KeyBoard States.
      for (u32 i = 0; i <= KEY_KEY_CODES_COUNT; i++)
      {
         keyState[i] = UP;
      }
      //Mouse states
      for (u32 i = 0; i <= 2; i++)
      {
         mouseButtonState[i] = UP;
      }
      //Mouse X/Y coordinates.
      mouse.X = 0;
      mouse.Y = 0;
      mouse.wheel = 0.0f;
   }
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

weloveyouclark22 wrote:

Code: Select all

      for (u32 i = 0; i <= KEY_KEY_CODES_COUNT; i++)
      for (u32 i = 0; i <= 2; i++)
You try to write beyond the array bounds. Try

Code: Select all

 for (u32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
Likewise for the mouse buttons.
"Whoops..."
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

randomMesh wrote:
weloveyouclark22 wrote:

Code: Select all

      for (u32 i = 0; i <= KEY_KEY_CODES_COUNT; i++)
      for (u32 i = 0; i <= 2; i++)
You try to write beyond the array bounds. Try

Code: Select all

 for (u32 i = 0; i < KEY_KEY_CODES_COUNT; i++)
Likewise for the mouse buttons.
Tried that, and I surprisingly had no success. I have narrowed it down to this line:

Code: Select all

keyState[i] = UP;
I checked, and as of version 1.7.2 (version we are using) there are 255 key enumeration types. So I set the keyState array to hold 255 values, and the program still has a segmentation fault. I don't believe it would be the type of array called, which is defined as:

Code: Select all

keyStatesENUM keyState[255];
But then again, I am unsure.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Post by REDDemon »

yuo should now that sometimes enumerations starts from 1. maybe try to allocate 256 arrays instead of 255.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Tried that as well, still has a segmentation fault.
random
Posts: 158
Joined: Wed Aug 11, 2010 6:01 am

Post by random »

the fastest way would be to comment out the half code, and check out if the segmentation fault still happens.

if yes its in the part that is not commented out so comment that out whats uncommented andd try again, if then the segmentation fault is gone remove the commentation for the half of the half wherin the segmentation fault on... and so on.
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Tried that as well, the program has a segmentation fault when I have either for loop uncommented.
Seven
Posts: 1034
Joined: Mon Nov 14, 2005 2:03 pm

Post by Seven »

why do you use two different constants for the same value

keyStatesENUM keyState[255];


and

for (u32 i = 0; i <= KEY_KEY_CODES_COUNT; i++)


try using keyStatesENUM keyState[KEY_KEY_CODES_COUNT];
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

I don't think the problem is with the event receiver itself...
it works for me, even with the out-of-array-bounds loops !!! :lol:
but one thing I had to change, this function is outdated:

Code: Select all

virtual bool OnEvent(SEvent event)
it has to be:

Code: Select all

virtual bool OnEvent(const SEvent& event) 
so my question is: what Irrlicht version you're using ???
and if you're using one of the latest versions: how did you even get it to compile with this OnEvent function ??? :shock:

just in case you don't trust me, here is my small test code I used, it's exactly this event receiver...
I just copy/pasted it and even didn't format it, just changed the OnEvent declaration and the for loops:

Code: Select all

#include <irrlicht.h>
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

class MastEventReceiver : public IEventReceiver
{

protected:
// Enumeration for UP, DOWN, PRESSED and RELEASED key states. Also used for mouse button states.
enum keyStatesENUM {UP, DOWN, PRESSED, RELEASED};

// Enumeration for Event Handling State.
enum processStateENUM {STARTED, ENDED};

// Mouse button states.
keyStatesENUM mouseButtonState[2]; //Left(0), Middle(1) and Right(2) Buttons.

// Keyboard key states.
keyStatesENUM keyState[KEY_KEY_CODES_COUNT];

// Mouse X/Y coordinates and Wheel data.
struct mouseData
{
int X;
int Y;
float wheel; //wheel is how far the wheel has moved
};
struct mouseData mouse;

processStateENUM processState; // STARTED = handling events, ENDED = not handling events

virtual bool OnEvent(const SEvent&  event  )
{
bool eventprocessed = false;

//////////////////////////////
// Keyboard Input Event
//////////////////////////////
if (event.EventType == EET_KEY_INPUT_EVENT)
{
if (processState == STARTED)
{
// if key is Pressed Down
if (event.KeyInput.PressedDown == true)
{
// If key was not down before
if (keyState[event.KeyInput.Key] != DOWN)
{
keyState[event.KeyInput.Key] = PRESSED; // Set to Pressed
}
else
{
// if key was down before
keyState[event.KeyInput.Key] = DOWN; // Set to Down
}
}
else
{

// if the key is down
if (keyState[event.KeyInput.Key] != UP)
{
keyState[event.KeyInput.Key] = RELEASED; // Set to Released
}
}
}


eventprocessed = true;
}

//////////////////////////////
// Mouse Input Event
//////////////////////////////

if (event.EventType == EET_MOUSE_INPUT_EVENT)
{
if (processState == STARTED)
{
//Mouse changed position
if (event.MouseInput.Event == EMIE_MOUSE_MOVED)
{
mouse.Y = event.MouseInput.Y;
mouse.X = event.MouseInput.X;
}

//Wheel moved.
if (event.MouseInput.Event == EMIE_MOUSE_WHEEL)
{
mouse.wheel += event.MouseInput.Wheel;
}

//Left Mouse Button Pressed
if (event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[0] == UP || mouseButtonState[0] == RELEASED)
{
mouseButtonState[0] = PRESSED;
}
else
{
mouseButtonState[0] = DOWN;
}
}

//Left Mouse Button Rleased
if (event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
{
//
if (mouseButtonState[0] != UP)
{
mouseButtonState[0] = RELEASED;
}
}

//Middle Mouse Button Pressed
if (event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[1] == UP || mouseButtonState[1] == RELEASED)
{
mouseButtonState[1] = PRESSED;
}
else
{
mouseButtonState[1] = DOWN;
}
}

//Middle Mouse Button Rleased
if (event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP)
{
//
if (mouseButtonState[1] != UP)
{
mouseButtonState[1] = RELEASED;
}
}

//Right Mouse Button Pressed
if (event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
{
//
if (mouseButtonState[2] == UP || mouseButtonState[2] == RELEASED)
{
mouseButtonState[2] = PRESSED;
}
else
{
mouseButtonState[2] = DOWN;
}
}

//Right Mouse Button Rleased
if (event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
{
//
if (mouseButtonState[2] != UP)
{
mouseButtonState[2] = RELEASED;
}
}
}


eventprocessed = true;
}


return eventprocessed;
}


//////////////////////
// Public functions
//////////////////////
public:

float mouseWheel()
{
return mouse.wheel;
}

int mouseX()
{
return mouse.X;
}

int mouseY()
{
return mouse.Y;
}

bool leftMouseReleased()
{
if (mouseButtonState[0] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool leftMouseUp()
{
if (mouseButtonState[0] == RELEASED || mouseButtonState[0] == UP)
{
return true;
}
else
{
return false;
}
}

bool leftMousePressed()
{
if (mouseButtonState[0] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool leftMouseDown()
{
if (mouseButtonState[0] == PRESSED || mouseButtonState[0] == DOWN)
{
return true;
}
else
{
return false;
}
}

bool middleMouseReleased()
{
if (mouseButtonState[1] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool middleMouseUp()
{
if (mouseButtonState[1] == RELEASED || mouseButtonState[1] == UP)
{
return true;
}
else
{
return false;
}
}

bool middleMousePressed()
{
if (mouseButtonState[1] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool middleMouseDown()
{
if (mouseButtonState[1] == PRESSED || mouseButtonState[1] == DOWN)
{
return true;
}
else
{
return false;
}
}

bool rightMouseReleased()
{
if (mouseButtonState[2] == RELEASED)
{
return true;
}
else
{
return false;
}
}
bool rightMouseUp()
{
if (mouseButtonState[2] == RELEASED || mouseButtonState[2] == UP)
{
return true;
}
else
{
return false;
}
}

bool rightMousePressed()
{
if (mouseButtonState[2] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool rightMouseDown()
{
if (mouseButtonState[2] == PRESSED || mouseButtonState[2] == DOWN)
{
return true;
}
else
{
return false;
}
}//

bool keyPressed(char keycode)
{
if (keyState[keycode] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool keyDown(char keycode)
{
if (keyState[keycode] == DOWN || keyState[keycode] == PRESSED)
{
return true;
}
else
{
return false;
}
}

bool keyUp(char keycode)
{
if (keyState[keycode] == UP || keyState[keycode] == RELEASED)
{
return true;
}
else
{
return false;
}
}

bool keyReleased(char keycode)
{
if (keyState[keycode] == RELEASED)
{
return true;
}
else
{
return false;
}
}


// This is used so that the Key States will not be changed during execution of your Main game loop.
// Place this at the very START of your Main Loop
void endEventProcess()
{
processState = ENDED;
}

// This is used so that the Key States will not be changed during execution of your Main game loop.
// Place this function at the END of your Main Loop.
void startEventProcess()
{

processState = STARTED;
//Keyboard Key States
for (int i = 0; i < KEY_KEY_CODES_COUNT; i++)
{
if (keyState[i] == RELEASED)
{
keyState[i] = UP;
}

if (keyState[i] == PRESSED)
{
keyState[i] = DOWN;
}
}
//Mouse Button States
for (int i = 0; i < 2; i++)
{
if (mouseButtonState[i] == RELEASED)
{
mouseButtonState[i] = UP;
}

if (mouseButtonState[i] == PRESSED)
{
mouseButtonState[i] = DOWN;
}
}
//Mouse Wheel state
mouse.wheel = 0.0f;

}

void init()
{
//KeyBoard States.
for (int i = 0; i < KEY_KEY_CODES_COUNT; i++)
{
keyState[i] = UP;
}
//Mouse states
for (int i = 0; i < 2; i++)
{
mouseButtonState[i] = UP;
}
//Mouse X/Y coordenates.
mouse.X = 0;
mouse.Y = 0;
mouse.wheel = 0.0f;
}


};

int main(){
MastEventReceiver rcv;

	IrrlichtDevice* device = createDevice(EDT_DIRECT3D9, dimension2du(640, 480), 16, false, false, false, &rcv);
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();
	IGUIEnvironment* guienv = device->getGUIEnvironment();

rcv.init();

  smgr->addCameraSceneNode();

	while(device->run()){
	  rcv.endEventProcess();
		driver->beginScene(true, true, video::SColor(0,50,100,150));
		smgr->drawAll();
		guienv->drawAll();
		driver->endScene();
		
		if(rcv.keyDown(KEY_KEY_A)) printf(".");
		if(rcv.keyReleased(KEY_ESCAPE)) device->closeDevice();
		
	  rcv.startEventProcess();
	}
	device->drop();
	return 0;
}
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
weloveyouclark22
Posts: 12
Joined: Thu Feb 24, 2011 10:52 pm

Post by weloveyouclark22 »

Oh, well that is embarrassing. I thought the OnEvent function looked fishy, but I didn't touch it for some reason. And it created a chain of problems, because I had to change the object to a pointer, which messed a lot of things up in the code and apparently caused a segmentation fault. Nonetheless, thank you for pointing that out, I got the code to work.
Post Reply