Tutorial : Timing And Movement Part 2

A forum to store posts deemed exceptionally wise and useful
Post Reply

Did that tutorial help you ?

Yeah ! I liked it
12
86%
It was okay ...
1
7%
Leave me alone !
1
7%
 
Total votes: 14

Isometric God
Posts: 69
Joined: Sun Oct 12, 2003 3:42 pm
Location: Germany

Tutorial : Timing And Movement Part 2

Post by Isometric God »

Part 2 : Pausing your Irrlicht application
----------------------------------------------

I'm sure you often experienced the following problem : You are playing your favorite game when one of your friends calls you up and wants to chat. If your brain supports multi-tasking, you will be able to do both at a time without any performance loss. If not, you have to pause one of these tasks. For it might be hard to put your friend on "suspend" mode, we will try to pause the game. I don't have to go into detail any more, right ?

First, we somehow need to find out when to pause the application. The easiest way to do this, is to find out whether the window is the active one or not. Next thing to do is .... nothing ! Right! We have to stop rendering frames to the screen. When the user wants to continue playing, he or she re-actives the window and the application should continue rendering. Sounds easy, right ?
Well, there is one thing missing : every timer in the game will continue counting in pause mode. As mentioned in part 1 of this tutorial, the Irrlicht timer retrieves the number of milliseconds that have elapsed since the system was started. Of course, this is independent from whether the game is paused or not. So, if you pause the game and continue playing ten minutes later, the "in-game-time" will advance the full ten minutes. Thus, we need to measure the time we spent in "suspend mode" and subtract it from any future time measurement.

Let's start with the game loop :

Code: Select all

int main()
{
	...

	bool wasActive = true;

	while (g_pDevice->run())
	{
		if (!g_pDevice->isWindowActive())
		{
			if (wasActive)
			{
				g_pTimer->Pause();
				wasActive = false;
			}

			Sleep(100);

			continue;
		}

		if (!wasActive)
		{
			g_pTimer->UnPause();
			wasActive = true;
		}

		...
		
		render

		...

	}

}

The bool wasActive keeps track of the state of the application. If the old state was active and the new one is inactive pause the game and vice versa. For the case that the game is inactive, we force the thread to sleep for some time and test again for activity. Keep in mind, that the rendering code is NOT executed. The sleeping time ( and thus the latency ) is comparativly high, because we want to gain as much CPU power as possible. A max. latency of 1/10 of a second when returning to the game does not matter really...

That's it ! Now we solely need to implement the Pause() and UnPause() functions in the CTimer class. As mentioned earlier we need to keep track of the time that passes while the game is paused. Thus, we add a member m_TotalPause to store the total amount of paused time and m_DeltaPause to keep track of the time passed since Pause(..) was called last.

Code: Select all

void Pause()
{
	m_DeltaPause = g_pDevice->getTimer()->getTime();
}

void UnPause()
{
	m_TotalPause += g_pDevice->getTimer()->getTime() - m_DeltaPause;
	m_DeltaPause = 0;
}

With some small modifications to CalcDeltaTime() the m_Time member will be the same before and after pausing. A nice side effect is that m_Time is the time the window is active. So to speak m_Time gives the time the user has been playing your game.

Code: Select all

void CalcDeltaTime()
{
	u32 old_time = m_Time;
	m_Time = g_pDevice->getTimer()->getTime() - m_TotalPause;
	m_DeltaTime = m_Time - old_time;
	m_TimeFactor = m_DeltaTime * 0.001f;
}
To avoid calling the Irrlicht time twice, we store the "old" time value in a temporary variable. Everything else should be self-explaining I hope. The full source code can be downloaded from my website.
http://eve-corp.com/Raptor/zip/timer.zip
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

err, sorry but where did you get Global.h from?
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
Isometric God
Posts: 69
Joined: Sun Oct 12, 2003 3:42 pm
Location: Germany

Post by Isometric God »

The Global.h contains the pointer to the Irrlicht device ( g_pDevice ).
It looks like this :

Code: Select all

#ifndef _GLOBAL_H_
#define _GLOBAL_H_

#include "Irrlicht/irrlicht.h"

using namespace irr;

extern IrrlichtDevice       *g_pDevice;   // defined in main.cpp
extern video::IVideoDriver  *g_pDriver;
extern scene::ISceneManager *g_pSceneMgr;
extern gui::IGUIEnvironment *g_pGUIEnv;

#endif
hope that helps ..
VeneX
Posts: 228
Joined: Sun Nov 30, 2003 3:32 pm
Location: The Netherlands
Contact:

Post by VeneX »

At #include "Irrlicht/irrlicht.h", he can't find the file. When I try to change it to Irrlicht.h he say's:
LIBCD.lib(crt0.obj) : error LNK2001: unresolved external symbol _main
Debug/Timer.exe : fatal error LNK1120: 1 unresolved externals

Sorry but 0.4.2 is messy
Visit my website @ www.venex.be
Plethora project will be added to the site
AMD AthlonXP 2600+, 512MB DDR, Radeon M10 (mobile 9600) PRO 64MB, WinXP
FleshCrawler
Posts: 108
Joined: Fri Aug 22, 2003 1:04 pm
Location: Kerkrade, Netherlands
Contact:

Post by FleshCrawler »

have you created a win32 windows app or a win32 console app?

if you have console you need int main()

if windows you need:
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT ) // this comes from the TechDemo source :P
I've been absent for really long, but i'm ready to reign my terror on you once again, mwuahahahahaha
DanielBocksteger
Developer
Posts: 25
Joined: Tue Jan 21, 2014 9:15 pm
Location: Goch, NRW, Germany
Contact:

Re: Tutorial : Timing And Movement Part 2

Post by DanielBocksteger »

In case you use this code to pause the rendering... The hole Programm/App is sleeping as well, isn't it?

I'm not abled to pause the rendering without pausing the App too.
Best regards,
Daniel Bocksteger

German iOS Developer born in '95.
AReichl
Posts: 268
Joined: Wed Jul 13, 2011 2:34 pm

Re: Tutorial : Timing And Movement Part 2

Post by AReichl »

and after 11 years another question:

Can't we just use the virtual timer with it's start(), stop() and setSpeed(...) functions?
That should only slow down all Irrlicht parts but not the "rest".
Post Reply