(C++) Simple to use Event Receiver class for Irrlicht 1.3

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

(C++) Simple to use Event Receiver class for Irrlicht 1.3

Post by Mastiff »

This is version 1.2a of the MastEventReceiver event receiver class.

Features are:
Four Key/Button states:
Pressed (occurs once, the first time a key/button is pressed)
Down (if the key/button is pressed or down)
Released (occurs once, the first time a key/button is released)
Up (if the key/button is released or up)

Simple functions to check for key states:
keyPressed()
keyDown()
keyReleased()
keyUp()
The same for Mouse button states:
leftMousePressed()
leftMouseDown()
leftMouseReleased()
leftMouseUp()

middleMousePressed()
middleMouseDown()
middleMouseReleased()
middleMouseUp()

rightMousePressed()
rightMouseDown()
rightMouseReleased()
rightMouseUp()
Plus Mouse X/Y and Wheel data:
MouseX()
MouseY()
MouseWheel()


The class uses an array for storing key and button states, providing constant events for handling smooth movement.

Comments and suggestions are welcome.

I hope people find use for this class and enjoy using it.

If you have any questions on how to use the class or problems with it feel free to post them here.

The following is the code for version 1.2a of MastEventReceiver.cpp

Code: Select all

/// ==================================================================================================
/// 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/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[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;
	}


};
/// ==========================================
/// END OF MastEventReceiver
/// ==========================================

Last edited by Mastiff on Tue Jun 19, 2007 6:54 am, edited 6 times in total.
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
Halan
Posts: 447
Joined: Tue Oct 04, 2005 8:17 pm
Location: Germany, Freak City
Contact:

Post by Halan »

why not use an enumeration instead of defines?

greets,
halan
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

And why not fixing the things already mentioned in the other thread?
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

The class is fully functional.
Vitek helped me solve the problem in my last thread.
All unneeded code was also removed.

To Halan:
Your right an enumeration would probably be better, I'll update it later.
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Post by GameDude »

This is easy to understand and well written. Good job.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Oh yes, you're right. I find the return statements hard to read so I misread these things. Why do you do an if to decide whether you return true or false? Just return the evaluated expression.
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

I've now added support for the mouse buttons (left,middle,right).

I'll work on the Mouse Wheel and X/Y position features later, I was puking my guts out yesterday :(
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
Arthur
Posts: 11
Joined: Wed May 30, 2007 4:49 pm

Post by Arthur »

hio,
why does this not function?

Code: Select all

while(device->run())
	if (device->isWindowActive())
	{
		Receiver.endEventProcess();
		
		driver->beginScene(true, true, 0);

		smgr->drawAll();
		driver->endScene();


		if (Receiver.leftMousePressed())
		{
			BoxNode->setPosition(vector3df(-1,0,0));
		}

		Receiver.startEventProcess();	
	}


	device->drop();
	return 0;
}
mfg
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

To Arthur:

First we need to know, what you are expecting it to do?

Another thing that would help is if you give us your full program code to look at.

Also are you getting compiler errors? If so what do they say?


Currently the only things I can think of that could be wrong are:

A) you expect BoxNode to move a considerable amount, currently the amount your moving it with BoxNode->setPosition(vector3df(-1,0,0)); is an extremely small amount and you may not notice it move, plus it will only ever move once, as it's position will always be set to the same location every time you press the mouse button.

B) your getting a compiler error from something wrong with your code.

C) your Receiver Class is not passed into your Irrlicht Device, like so:
device = createDevice(EDT_OPENGL, dimension2d<s32>(640, 480),16,false, false, false, &Receiver);
this must come after you create an instance of the class
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
Arthur
Posts: 11
Joined: Wed May 30, 2007 4:49 pm

Post by Arthur »

Oh Thanks^^ its function^^

it was case C) ^^ ups my mistake :oops:

thanks for this class, good work

mfg from germany^^
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

Your welcome I'm glad your problem is fixed :)
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

I have now finished adding support for the mouse X/Y positions and mouse Wheel data.
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Post by GameDude »

So its complete then?
olivehehe_03
Posts: 157
Joined: Tue Mar 20, 2007 8:30 am

Post by olivehehe_03 »

Nice code, I'm copying and pasting bits into my own code, my event receiver was a bit messed up :D

EDIT: I made a small modification to the public functions for detecting key input, instead of passing a char to keyDown(), keyUp(), keyPressed() and keyReleased() you can pass a EKEY_CODE to it, for example keyDown(KEY_KEY_W). If you want to use it, just paste this either over the originals to replace them, or just paste them after the originals so you can use either method.

Code: Select all

		bool keyPressed(EKEY_CODE keycode)
		{
			if (keyState[keycode] == PRESSED)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		bool keyDown(EKEY_CODE keycode)
		{
			if (keyState[keycode] == DOWN || keyState[keycode] == PRESSED)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		bool keyUp(EKEY_CODE keycode)
		{
			if (keyState[keycode] == UP || keyState[keycode] == RELEASED)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		
		bool keyReleased(EKEY_CODE keycode)
		{
			if (keyState[keycode] == RELEASED)
			{
				return true;
			}
			else
			{
				return false;
			}
		}
Tell me what you cherish most. Give me the pleasure of taking it away.
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

To Game Dude:
Yes for all practical purposes it's now complete, I'll update it if anything in Irrlitch changes.

To olivehehe_03:
You where already able to do that without modifications, I guess I should have stated that, either way works fine.
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
Post Reply