Problem with ifs

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.
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Bug found for certain.

Post by VioletAlixe »

While implimenting a simple "if" block, I came across a problem of Irrlicht "testing" ifs.

Explanation:

I made an if that can turn off whether or not to read a keyboard input as
well as a toggle for turning off and on the switch.

IE:

~if (keyboardstate == true)
~{
~ if (inputKey)
~ {
~ do this;
~ }
~}
~
~if (toggleKey)
~{
~ if (keyboardstate == true)
~ {
~ keyboardstate = false;
~ }
~ else
~ {
~ keyboardstate = true;
~ }
~}


It's pretty simple to look over. If it's in one state, it will do the "do this",
if it's in the other, it won't. Right? Right.

Oh wait. Except it doesn't.

This is what it actually does:

If the keyboard inputs are allowed, it does the command with no problem.
If the keyboard inputs are not allowed, it "tests" the command, and then
doesn't do it. By tests, I mean, it tries to skip past the if, then comes back
and doesn't do it depending on certain limitations.

For example, if I only have an int that can ++ up to say 5, if I have
something that looks like this:

~if (i <= 5)
~{
~ i++;
~}

Irrlicht will actually first GO PAST 5, then fix the error. So i will be 6 for a second.

Now, you may think this is fine, as long as it fixes it immediately, but
going back to the first example...

The "testing" doesn't matter, it fixes the problem, until I turn the inputs
back on. It actually performs the test then and doesn't fix it this time.

What I mean is, say I have the inputs set to off, and I input once. It will
"test" and fix it immediately, and there's no problem. Once I turn the
inputs back on though, the "test" from before shows up, and is not fixed.

I have checked this on multiple ifs and it appears only to happen in the block of code where the device is running. Help plz.
Dark_Kilauea
Posts: 368
Joined: Tue Aug 21, 2007 1:43 am
Location: The Middle of Nowhere

Post by Dark_Kilauea »

This isn't a problem with irrlicht, what compiler are you using?
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

See at first I thought it wasn't a problem with Irrlicht either, however, the problem only happens during the run process, which is part of Irrlicht. I'm using Visual Studio.
CuteAlien
Admin
Posts: 9687
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Your first thought was correct. This is no problem with Irrlicht. Irrlicht will not change the behavior of your c++ compiler.

And it's really posted in the wrong thread. If you can make your example more concrete you might create a new thread in the beginner forum and try to get help there. Most likely it's that you don't know how keyrepeat works or something like that.
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
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Split and moved from the bug forum.
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

Well that's kinda rude, but thanks. For one, this was in the right thread, I'm testing the new beta for errors.

For two, before you flat out deny my discovery and come up with a random answer from who knows where, you should perhaps go and test it yourself.

Finally, again, the first thought was changed because the problem only happened while the device was running. That means the compiler can handle ifs when it's not running. That means that there is something wrong with how the device is running. The device, of course, being specific to Irrlicht.

Side note: I'm running Visual Studio C++, which is a fairly reliable compiler. If you think it /is/ my compiler, perhaps you could test it yourself on yours before you claim the bug is non-existing.


Edit: posted later. This should not have been moved as it was moved on a supposition, with no evidence that it wasn't a bug.
CuteAlien
Admin
Posts: 9687
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Sorry, but we really don't need evidence for that. It's simply that Irrlicht won't change the behavior of if's. I am 100% certain of this. If you knew enough c++ you would know how compilers work and would never propose something like this.

Just for info. What happen on/after an if (and any other c++ label) is decided at compiletime. That information is written in an object file (those files with ending .o). And those files are linked together at link-time with the irrlicht library. So at that time your code is already written by the compiler and no longer changed. Except with some really evil tricks which would need work and won't happen by accident.

Always do search the bug on your side first. For the code you posted it is *obvious* that Irrlicht *can't* be responsible for the problem. There might be a problem if you post more code (more likely not). But for the given code we are simply certain.
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
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

Okay simply saying that you are certain doesn't make it true. Here's some code for you that will prove that it's not just my compiler.


Code: Select all



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

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

	#ifdef _IRR_WINDOWS_
	#pragma comment(lib, "Irrlicht.lib")
	#endif

// Declare device.
IrrlichtDevice* device = 0;

// Major nodes.
scene::IAnimatedMeshSceneNode* nodeHero = 0;

// States

	bool screenState;
		//0 = Input screen type.  //Create a class for menus.
		//1 = Hero screen type.

// Input.

	//Zoom and free rotate camera.
	bool inputUp = false;
	bool inputDown = false;

	//Input buttons.
	bool inputEsc = false;

// Event reciever class.
class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(const SEvent& event)
	{ 
		if (event.EventType == EET_KEY_INPUT_EVENT)
		{
			switch(event.KeyInput.Key)
			{
				// Camera.
				case KEY_UP:
				inputUp = event.KeyInput.Key;
				break;
				case KEY_DOWN:
				inputDown = event.KeyInput.Key;
				break;
				// Inputs.
				case KEY_ESCAPE:
				if (!event.KeyInput.PressedDown)
				{
					inputEsc = event.KeyInput.Key;
				}
				break;
			}
		}
		return false;
	} 
 };



// Main program initiation.
int main()
{
	// deviceType: EDT_BURNINGSVIDEO, EDT_NULL, EDT_DIRECT3D8 , EDT_DIRECT3D9, or EDT_OPENGL. 
	// windowSize: Size of the Window or FullscreenMode to be created.
	// bits: 16 or 32. This parameter is ignored when running in windowed mode.
	// fullscreen
	// stencilbuffer: Specifies if we want to use the stencil buffer for drawing shadows.
	// vsync: only useful in fullscreen mode.
	// eventReceiver:

	// Set the driver base.
	video::E_DRIVER_TYPE driverType = video::EDT_SOFTWARE;

	// Ask user for prefered driver.
	printf("Please select your prefered renderer.\n"\
			" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"\
			" (d) Software Renderer\n (e) Apfelbaum Software Renderer\n"\
			" (f) NullDevice\n (otherKey) exit\n\n");

	// Wait for input char.
	char i;
	std::cin >> i;

	switch(i)
	{
		case 'a': driverType = video::EDT_DIRECT3D9;break;
	    case 'b': driverType = video::EDT_DIRECT3D8;break;
		case 'c': driverType = video::EDT_OPENGL;   break;
		case 'd': driverType = video::EDT_SOFTWARE; break;
		case 'e': driverType = video::EDT_BURNINGSVIDEO;break;
		case 'f': driverType = video::EDT_NULL;     break;
		default: return 1;
	}	

	// Create the reciever for input for device implimentation.
	MyEventReceiver receiver;

	// Create device and exit if creation failed.
	device = createDevice( driverType, core::dimension2d<s32>(640, 480), 16, false, false, false, &receiver);
	if (device == 0)
		return 1;
	
	// Caption Window
	device->setWindowCaption(L"Setting up.");

	// Name the Video Driver and Scene Manager for use as a variable.
	IVideoDriver* driver = device->getVideoDriver();
	ISceneManager* smgr = device->getSceneManager();

	// Load nodes (create function later, define a class for which size and node are brought in)

	IAnimatedMesh* meshHero = smgr->getMesh("../../media/sydney.md2");
	nodeHero = smgr->addAnimatedMeshSceneNode( meshHero );

	if (nodeHero)
	{
		nodeHero->setMaterialFlag(EMF_LIGHTING, true);
		nodeHero->setMD2Animation ( scene::EMAT_STAND );
	} 
	
	scene::ICameraSceneNode* nCam = smgr->addCameraSceneNode(0, vector3df(0, 0, 0));
	

	vector3df heroPosition;
	vector3df alteredPosition;
	vector3df heroDirection;
	float faceDirection;

	// Initializations
	int zoomLevel = 3;
	screenState = false;

	float camXf;
	float camYf;
	float camZf;

	while(device->run())
	{

		heroPosition = nodeHero->getPosition();
		heroDirection = nodeHero->getRotation();

		faceDirection = ((heroDirection.Y+90) * 3.14 / 180);

		// Check State.
		if (screenState == true) // While screen state is in hero state.
		{
			// Begin movement operations

			if (inputUp && screenState)
			{
				if (zoomLevel > 2)
				{
					zoomLevel--;
					inputUp = false;
				}
			}
			if (inputDown)
			{
				if (zoomLevel < 4)
				{
					zoomLevel++;
					inputDown = false;
				}
			}

			nodeHero->setRotation(heroDirection);
			nodeHero->setPosition(heroPosition);
			// End movement operations

			// Begin camera operattions
			camXf = (heroPosition.X-sin(faceDirection) * 15 * zoomLevel * zoomLevel);
			camZf =(heroPosition.Z-cos(faceDirection) * 15 * zoomLevel * zoomLevel);
			camYf = heroPosition.Y + 30 + (20 * (zoomLevel - 2));

			// Post hero placement determination camera operations.

			//nCam->setTarget(heroPosition);
			alteredPosition = heroPosition;
			alteredPosition.Y += 15;
			nCam->setTarget(alteredPosition);
			nCam->setPosition(vector3df(camXf,camYf,camZf));
			// End camera operations
		}
		
		//Debug only; state toggler.
		if (inputEsc)
		{
			if (!screenState)
			{
				screenState = true;
				inputEsc = false;
			}
			else if (screenState)
			{
				screenState = false;
				inputEsc = false;
			}
		}


		driver->beginScene(true, true, SColor(255,100,101,140));
		smgr->drawAll();

		driver->endScene();
	}

	device->drop();
	return 0;
}



Press the escape key to toggle the functions, if you hadn't read, and note that I hand deleted a lot of comments, so if there's something out of place, I may have simply missed it.
Last edited by VioletAlixe on Fri Oct 05, 2007 12:42 am, edited 1 time in total.
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

Double posting to ensure that I don't accidentally delete any code from above.

NOTE: to test this bug, follow these steps:

1. Debug program.
2. Select any visual driver.
3. Press the "Esc" key to toggle the camera zoom option.
4. Freely move around with the up and down keys as you see fit.
5. Press "Esc" again to toggle off the camera zoom.
6. Notice that the camera is not moving now.
7. Press "Esc" again after trying to move the camera and failing because of the above.
8. Notice that the camera now has moved once because of the "testing" issue.
CuteAlien
Admin
Posts: 9687
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

VioletAlixe wrote:Okay simply saying that you are certain doesn't make it true. Here's some code for you that will prove that it's not just my compiler.
Which is why I tried to explain why it can't happen. Once more: Irrlicht is not responsible for your if's and it won't change your if's. It simply has nothing at all to do with that part. There is no connection. That's why I am so extremely certain that it's not an Irrlicht problem.

And to debug your code is something you can do yourself. Just add some logging to the places where inputEsc is set and where it is used. My guess is some stuff like key-repeating is bothering you. Or maybe you get the up twice? This could be a bug (maybe). I can just give you one hint: The functioning of any if's does not, has never, and won't change anytime in the future by using Irrlicht.
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
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

Alright. I've posted my code for YOU to debug so YOU can see if there's something wrong with just my code or just my compiler but comparing it to YOURSELF. I am aware that I can debug it. I /did/ debug it. That's how I know it doesn't work. The issue isn't with repeating keys. It's a state-based problem.

READ THIS PART AT LEAST:

What is supposed to happen:

If key is being allowed to be pressed:
DO SOMETHING.
If not:
DO NOTHING.



What is actually happening:

If key is being allowed to be pressed:
DO SOMETHING.
If not:
DO SOMETHING ONCE BUT DON'T SHOW IT UNTIL KEYS ARE ALLOWED.
CuteAlien
Admin
Posts: 9687
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Holy sh1t! I really forgot I'm just existing to help you find bugs in trivial applications. Sorry, I might take a look at it tomorrow, but for now I'm just laughing too hard.

Just one hint - you mix integer and bools. You should not.
Like
inputUp = event.KeyInput.Key;

I really have no time atm to find out what irrlicht does here - but some systems would for example return stuff like KEY_UP as two characters where one of them is 0x00. Which would set that to false. What you want at those places is just setting it to true. Maybe that's it already.

Edit: Just in case you didn't notice. The above message where there to help you. You look for the bug in the wrong place and that's all what this is about. If you don't want that information feel free to ignore it.
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
VioletAlixe
Posts: 28
Joined: Thu Oct 04, 2007 9:03 pm

Post by VioletAlixe »

Nice job doing nothing. You managed to succeed in proving that you don't want to prove anything.

By the way, it's not mixed, it's whether the event exists in the context.

Stop giving tips when you have no idea what you're talking about.
CuteAlien
Admin
Posts: 9687
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

VioletAlixe wrote: Stop giving tips <snip>
Ok.
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
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Violet,

You are totally off base here. CuteAlien is right, there is no way in hell that the compiler is generating bad code because you're using Irrlicht. The problem is that you are using Irrlicht incorrectly, and you are jumping to conclusions. Honestly.

From looking at your code I would guess that the problem is in the event receiver [as pointed to by CuteAlien]. You are misinterpreting the use of the KeyInput.Key member. That is the key code for the key that was pressed, but you are using it like it is an indicator to see if the key is pressed down or not.

Travis
Post Reply