(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.
GameDude
Posts: 498
Joined: Thu May 24, 2007 12:24 am

Post by GameDude »

OK, that's cool, good job again on your code.
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

It looks really nice and efficient and I think ill start using it.
Although is has the basic features well-coded I believe it would be much more better with more new and advanced features. I think you should develop it to something bigger which can handle more complicated situations. If I'll have any ideas trust me I'll put them up here, but still, this class is a Well done work.
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
prajay.shetty
Posts: 14
Joined: Tue Jun 05, 2007 8:04 am
Location: INDIA,MAHARASHTRA

Post by prajay.shetty »

can u please correct out the problem in it she dont move when i press this button w continously this code compiles with out any error and executes too but when i press w that time she dont move i think so this is the right post to check this code with mastevent receiver aurthor plzz help out

Code: Select all

#include <irrlicht.h>
#include <iostream>

using namespace irr;

using namespace core;

using namespace io;

using namespace gui;

using namespace scene;

using namespace video;

#include "MastEventReceiver.cpp"

#pragma comment(lib, "Irrlicht.lib")

int main()
{
	
  MastEventReceiver receiver;
	
	  
  IrrlichtDevice *device =
		
	createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(1024, 768),16,false,false,false,&receiver);

   if(device==0)
   {
	   return 1;
   }
	
	IGUIEnvironment *guienv = device->getGUIEnvironment();

   ISceneManager *smgr = device->getSceneManager();

   IVideoDriver *driver = device->getVideoDriver();

   //load map
   
   device->getFileSystem()->addZipFileArchive("./../media/map-20kdm2.pk3");

   
   
   scene::  IAnimatedMesh *mesh = smgr->getMesh("20kdm2.bsp");

   ISceneNode *node =0;

   if (mesh)    
	   
	   node = smgr->addOctTreeSceneNode(mesh->getMesh(0));
   
   if (node)    
	   
	   node->setPosition(core::vector3df(-1300,-144,-1249));

   //load object
   
   scene::IAnimatedMeshSceneNode* node1 = 0; 

   
   scene::IAnimatedMesh* mesh1 = 0; 

   
   mesh1 = smgr->getMesh("sydney.md2"); 
  
   node1 = smgr->addAnimatedMeshSceneNode( mesh1 ); 

   node1->setPosition(core::vector3df(0,0,30)); 

   node1->setMaterialFlag(video::EMF_LIGHTING, false); 

   
  
   
 if(mesh)

   {
	   smgr->addOctTreeSceneNode(mesh->getMesh(0));

   }

   if(node)
   {
         node->setPosition(core::vector3df(-1300,-144,-1249));
   }

   smgr->addCameraSceneNodeFPS();

   while(device->run())

   {
	  
	 
	   
	   receiver.endEventProcess();
	   
	  
	   driver->beginScene(true,true,SColor(0,100,100,133));

	   smgr->drawAll();

	   guienv->drawAll();

	

	   driver->endScene();

      
	   
	   if(receiver.keyPressed(KEY_KEY_W))
	   {
	   

		   core::vector3df v = node1->getPosition();

		   v.X = v.X+2;

		   node1->setPosition(v);

   
		   node1->setMD2Animation(scene::EMAT_RUN); 
	   }

	   if(receiver.keyReleased(KEY_KEY_W))
	   {
		   node1->setMD2Animation(EMAT_STAND);
	   
	   
   
	   
	   
	   }

	   
	   
	   
	   
	   
	   	   
	   receiver.startEventProcess();
   
   }

device->drop();

return 0;

}

thanks a lot for any help that u guys had given i triedieventreceiver but i then started using mastevent receiver as effeicient class but can u plzz correct out this probles for me Mastiff or any one who know to use masteventreceiver class plzzzzz
eneru
Posts: 40
Joined: Tue Apr 10, 2007 8:38 am

Post by eneru »

it doesn't work :'(

or to be more explicit, it works wonderfully but only for some time, after which the key input handler become mad >.>

i did this test :

Code: Select all

int i = 0;

if (eventReceiver.keyPressed('M'))
{
    cout << i << " ... pressed" << endl;
}

if (eventReceiver.keyDown('M'))
{
    i++;
    cout << i << endl;
}

if (eventReceiver.keyReleased('M'))
{
    cout << i << " ... released" << endl;
}
and as long as i don't keep "m" down for too long it works as intended, but if i keep it down i will get some messages saying it is pressed, randomly O.o


For the record, it screws up for the first time for i around 300 (it can be 230 as well as 440...), and after it failed the first time it fails regularly (between every 15 and 30 i steps)


I'm using linux + OpenGL and am desperate to find an answer :cry: (the mouse seems to not have this problem)
The worst is that the test seems to be good... but then how could this problem be solved ????
eneru
Posts: 40
Joined: Tue Apr 10, 2007 8:38 am

Post by eneru »

up !

it is a double post, but for the good hopefully as it works now !!! 8)

I am posting the code (there is not much really) so others can use it if they experience problems (@Mastiff : don't hesitate to use it too if you want ;) thanks for the original code btw ;))

Code: Select all

if (keyState[event.KeyInput.Key] == !DOWN)

instead of :

if (keyState[event.KeyInput.Key] == UP || keyState[event.KeyInput.Key] == RELEASED) 
(it is from the beginning of the onEvent function)


if other people could confirm it still works for them (especially windows users) it would be nice ;) (it would suck if what helped making it work for me screwed it up for others :p)
Mastiff
Posts: 17
Joined: Thu Apr 19, 2007 9:55 pm

Post by Mastiff »

To MasterGod:
Thanks much, and I might possibly expand it for more advanced features, possibly GUI events/user events.

Any idea's are welcome.

To prajay.shetty:

You should probably be calling:
eventReceiver.init();

just after you create the instance of the class.

And the problem is probably this:
if(receiver.keyPressed(KEY_KEY_W))

should be:

if(receiver.keyDown(KEY_KEY_W))


The key "Pressed" event only ever happens once, so your character will only move 2 units, which could hardly be visible.

The key "Down" event is always active if the key is held down, meaning it would constantly update it's position.

To eneru:

Are you placing:
receiver.endEventProcess();

at the start of your whileloop and

receiver.startEventProcess();

at the end of the loop?

I used your test code and it works perfectly for me(I used an object to hold the key down for quite a while even), I couldn't get it to go wrong on my Windows XP install. (currently dont have a working linux install to test on atm)

I even used the modified code you supplied and again nothing was wrong.

Since it works either way on my XP install I modified the code to work as the way you changed it since it obviously works for you and doesn't break the code.

It could have something to do with how Linux handles key events, either way it shouldn't happen anymore.
#include <"signature.h">

OS = Windows XP
IDE = Code::Blocks
Compiler = GCC MingW
eneru
Posts: 40
Joined: Tue Apr 10, 2007 8:38 am

Post by eneru »

ok, i don't have windows to test it but from what i understood the events are not dealt exactly the same way on windows or linux, thus the (weird) problem :)
If my hack still works on windows then the problem is completely solved ^^

and yes i placed the 2 methods well ;)


There is also another problem i had (though it should be the same on windows) : my GUI never got the events as your OnEvent method always return true if there was a mouse or keyboard event, and so irrlicht doesn't send the event to the GUI in case if it should be handled there !
I made this method to always return false as of now, and it works for the GUI now (and of course still works great for the keyboard and mouse)

and that's it, thanks again for your class ;)
Dukdalf
Posts: 24
Joined: Thu Jun 21, 2007 9:48 am

Very nice code, but ...

Post by Dukdalf »

Hi guys,

I was really clueless for implementing an event receiver in such a way that I could make use of it it a nice way! This looks very nice, and I will happily use it in my code. But I have a weird artifact!

My code was up adn running, I used the RTS camera, that uses its own event receiver internally which worked fine.;-) But after adding this event receiver, my camera moves forward and I cannot interact with my program at all.
Here are some snippets of my code:

Code: Select all

int main() {
        MastEventReceiver eventReceiver;
        eventReceiver.init();
        IrrlichtDevice* device;
        device = createDevice(video::EDT_DIRECT3D9, core::dimension2d<s32>(640,480),32,false,false,false,&eventReceiver);
..

..
        RTSCamera* camera = new RTSCamera(device,smgr->getRootSceneNode(),smgr,-1,1000.0f,10.0f,10.0f);
        camera->setPosition(core::vector3df(-500,3000,2500));
        camera->setTarget(core::vector3df(0.f,2500.f,2500.f));
..

..
	int lastFPS = -1;
	int xbox = 0 ;
	int zbox = 0 ;
	f32 xposbox = 0;
	f32 zposbox = 0;
	vector3df newpos;
	while(device->run())
	if (device->isWindowActive())
	{
		eventReceiver.endEventProcess();
		driver->beginScene(true, true, 0 );

		smgr->drawAll();
		env->drawAll();

		gui::ICursorControl* cursor = device->getCursorControl();
		core::vector3df intersection;
		core::triangle3df tri;
		
		mouseOverPlayerNode = smgr->getSceneCollisionManager()->getSceneNodeFromScreenCoordinatesBB(cursor->getPosition(),(0x01));
		
		if (mouseOverPlayerNode && eventReceiver.leftMouseDown()){
			if (smgr->getSceneCollisionManager()->getCollisionPoint(
				smgr->getSceneCollisionManager()->getRayFromScreenCoordinates(cursor->getPosition()), selector, intersection, tri))
				{
					xbox = int(intersection.X / 340);
					zbox = int(intersection.Z / 340);
					//cout << xbox << " " << zbox <<endl;	
					xposbox = xbox * 340.f + 170.f;
					zposbox = zbox * 340.f + 170.f;
					//cout << xposbox << " " << zposbox <<endl;
					newpos.set(xposbox,152.f,zposbox);
					mouseOverPlayerNode->setPosition(newpos);
				}
		}


		driver->endScene();

		// display frames per second in window title
		int fps = driver->getFPS();
		if (lastFPS != fps)
		{
			core::stringw str = L"Terrain Renderer - Irrlicht Engine [";
			str += driver->getName();
			str += "] FPS:";
			str += fps;

			device->setWindowCaption(str.c_str());
			lastFPS = fps;
		}
		eventReceiver.startEventProcess();
	}

	device->drop();
	return 0;
}
I did not change anything to the MastEventReceiver, besides the irrlicht.h include. It all compiles fine without any mayor bugs. I do get 4 times this warning:
Severity and Description Path Resource Location Creation Time Id
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 369 1185348358734 9095
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 381 1185348358734 9096
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 393 1185348358734 9097
array subscript has type `char' BB3d/src MastEventReceiver.cpp line 405 1185348358734 9098

but i guess those are harmless! they annoy me ofcourse, but I do not understand them either!

Hopefully somebody understands or can give me a pointer to what is going wrong.

Thanks in advance!
Just fooling around abit!
rooly
Posts: 224
Joined: Tue Oct 25, 2005 4:32 pm
Location: Louisiana, USA, backwater country
Contact:

Post by rooly »

hey, i found a bug in this code. in your mouse state array, you set it to have 2 places, yet you check for 3 in all your loops. you should change

Code: Select all

keyStatesENUM mouseButtonState[2];
to

Code: Select all

keyStatesENUM mouseButtonState[3];
When banks compete, you win.
When ISPs compete, you win.
When electronics retailers compete, you win.
When governments compete...you get drafted.
CuteAlien
Admin
Posts: 9733
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Tss, rooly - you could have mentioned the other bug as well...

As keyState has size KEY_KEY_CODES_COUNT the init() function should use

Code: Select all

for (int i = 0; i < KEY_KEY_CODES_COUNT; i++) 
instead of

Code: Select all

for (int i = 0; i <= KEY_KEY_CODES_COUNT; i++) 
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
denton
Posts: 3
Joined: Thu Aug 30, 2007 2:02 am

XkbSetDetectableAutoRepeat

Post by denton »

Spent a while tracking this bug down so I thought I'd share:

Under X11 it is apparently default behavior, when a user presses a key, to send a continuous stream of Released/Pressed messages. This will obviously confuse any system where you're trying to tell if a key has been "Pressed" for the first time.

There's a fix for this now, but it's not in CIrrDeviceLinux (yet?):
http://lists.freedesktop.org/archives/x ... 15819.html

So for the time being, I've added

Code: Select all

CIrrDeviceLinux:22
#include <X11/XKBlib.h>
...
CIrrDeviceLinux:528
// disable auto-repeat
        {
                Bool detectable_autorepeat_supported;
                XkbSetDetectableAutoRepeat(display,
                                           True,
                                           &detectable_autorepeat_supported);
        }
Which fixed everything and allows you to use this class as it was intended under linux. AFAIK you can't do this "outside" of the CIrrDeviceLinux class because there's no way to access the display variable "after the fact": http://kerneltrap.org/node/5960.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Thanks a lot for this bugfix. This bugged a lot of people for quite some time already. I have just commited the first part (the one you posted), but the link also contains a solution for older systems which I'll add.
benny53
Posts: 131
Joined: Fri May 26, 2006 10:21 pm
Location: Ohio

Post by benny53 »

the ICameraSceneNodeFPS does not respond(as in with the key codes it uses for moving). I guess I'll have to make a custom one,but thats even better,because irrlichts one doesn't allow jumping. But you may wanna take a look at that(I think I know why it wouldn't work though,because your event receiver over rides irrlichts? maybe? probably not actually).
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

I got some problems when trying to compile my app after included this
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyPressed(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:369: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyDown(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:381: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:381: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyUp(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:393: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:393: warning: array subscript has type ‘char’
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:: In member function ‘bool MastEventReceiver::keyReleased(char)’:
/home/leezhieng/Projects/GenetixMaterialEditor/control.h:405: warning: array subscript has type ‘char’
:: === Build finished: 0 errors, 6 warnings ===
MasterGod
Posts: 2061
Joined: Fri May 25, 2007 8:06 pm
Location: Israel
Contact:

Post by MasterGod »

There is a change that need to be made to work with SVN revision 1004+:
From:

Code: Select all

virtual bool OnEvent(SEvent event)
To:

Code: Select all

virtual bool OnEvent(const SEvent& event)
Image
Dev State: Abandoned (For now..)
Requirements Analysis Doc: ~87%
UML: ~0.5%
Post Reply