Page 1 of 1

Question for experienced programmer

Posted: Thu Jun 26, 2008 4:18 pm
by Balthazar
Well, need your help, guys!

I`m creating a small funny game on C++ in my free time. I`ve got a problem to set the same fps on different systems.

As I see it - there are two ways of doing this:
1. Using Sleep(x) function, where x- delay in milliseconds, that can be tweaked to set the default (for example 60 fps) speed.
2. Using tics. Measure system time ising GetSysTime() or GetTickCount() functions and see if 1/60 of sec is reached, then do next tick.

The problem with way 1 is that on different CPU on OS version Sleep function doesn`t works the same way, sometimes my game don`t react at all on changing lag... Maybe it is somehow connected to 2-core CPU.

With Tics stuff I`ve got another problem - it seem like I have to run application and do all drawing all the time, except of important calculations, that are take place when tick occured.

How should i arrange fps limitation the right way?

Re: Question for experienced programmer

Posted: Wed Jul 08, 2009 8:06 pm
by Balthazar
Here`s the game I`m making. FPS detection is locked, I`ve got nearly 85 on my PC.

Keys are:
Coursor for movement/rotation
Space for shooting
PgUP/PgDown to zoom
F1 - toggle Fullscreen mode on/off
ESC - quit.

Re: Question for experienced programmer

Posted: Wed Jul 08, 2009 10:19 pm
by milipili
You can use a similar mecanism to TA3D.

Something like that :

Code: Select all

static void DrawMyObjects()
{
	// Put your code here to render all your 3D objects
	// OpenGL / DirectX
}


int main()
{
	// FPS Limit
	// The VSync should be disabled (otherwise the fps will be stuck to 60 - 59.9 actually)
	unsigned int fpsLimit = 35; /* Frame per Second */

	// Duration of a single frame (in ms)
	unsigned int fpsDelta = 1000 / fpsLimit;
	if (fpsDelta < 4)
	{
		// We have not enough precision with milli seconds to limit the number of FPS
		fpsLimit = 0; // Disabling the limit
	}

	// The time in milli seconds when the last frame was processed
	// This variable will be used to reduce the number of FPS
	uint64 lastCheckpointLimit = 0;

	// We would like to compute the number of FPS every second
	// But we have to wait a little that the system is stable.
	// The first FPS value will less than the real one, psychology better
	uint64 lastCheckpointFPSCount = TimeInMilliSeconds() + 400; // ms, arbitrary value to delay the first calculation

	// The number of FPS since the last check
	unsigned int frameCountSinceLastTime = 0;
	// FPS
	unsigned int fpsCount = 0;

	// Entering the main loop
	while (true)
	{
		uint64 newCheckpoint = TimeInMilliSeconds();

		if (fpsLimit)
		{
			// We have to limit the number of FPS
			//
			// We will compute the time (in milliseconds) that the last frame took
			// to be rendered.
			uint32 delta = (uint32)(newCheckpoint - lastCheckpointLimit);
			while (delta < fpsDelta)
			{
				// We could only sleep for 1 ms. But we can safely reduce the number
				// of calls to the sleep routine (assuming fpsDelta >= 4).
				SleepMilliSeconds((delta >> 2) /* div 4 */);
				// We may have to wait again. Checking...
				newCheckpoint = TimeInMilliSeconds();
				delta = (uint32)(newCheckpoint - lastCheckpointLimit);
			}
			// Reset
			lastCheckpointLimit = newCheckpoint;
		}

		// FPS
		if (newCheckpoint - lastCheckpointFPSCount >= 1000)
		{
			// FPS ?
			fps = round((double)frameCountSinceLastTime / (((double)(newCheckpoint - lastCheckpointFPSCount)) / 1000.));
			std::cout << fps << " FPS" << std::endl;
			// Reset
			lastCheckpointFPSCount = newCheckpoint;
			frameCountSinceLastTime = 0;
		}

		// Put your Code for drawing 3D Objects here (OpenGL/DirectX)
		DrawMyObjects();

		// A frame has been rendered
		++frameCountSinceLastTime;
	}
}
Obsviously, GetTickCount() is not recommended. It is a Windows Only routine.
If you don't have an implementation for TimeInMilliSeconds(), I have one somewhere and it will be added to Yuni::Core. Just ask.
If you're looking for SleepMilliSeconds() : http://trac.libyuni.org/browser/trunk/s ... em/sleep.h (.cpp)

The code performace can be improved, but it should be fine for now.

Re: Question for experienced programmer

Posted: Wed Jul 08, 2009 10:20 pm
by zuzuf
There are 3 ways of handling time in a game:
  • you can set a fixed FPS rate but it'll prevent your game from running correctly on slow machines or if there is a problem like vertical refresh rate synchronization that you may not override
  • you can use a tick based system (like in TA3D), then ticks (simulation) and rendering doesn't have to be synced, you just set your rendering rate to be at least screen refresh rate and run simulation in an other thread
  • you can run at maximum speed and between each frame you compute a simulation step equivalent to the time taken to render the last frame (simulation and rendering are synced and can be in the same thread, also you may split that step into smaller one if it's too big to avoid losing too much precision)
for any of these methods you'll need a (precise) timer with a time resolution of at least 1ms.
If you want to lower your frame rate to something you chose, then just compute the difference of your timer value between two frames and wait required_ms_for_my_target_fps - time_taken_to_render_my_last_frame :)
Also it's better to always use a fixed time as the time origin if possible instead of doing incremental stuffs (physics can and will probably be experimental, but precise stuffs cannot).

I don't know what library you use but prefer something that is designed for game programming and which is crossplatform like SDL or Allegro (now that I know both I prefer SDL :P).

Your game runs at 107fps on my machine (using wine), I couldn't zoom :( but I could fire and move (I noticed your collision detector seems to be position based, so if the bullet is moving fast it can go through the box)

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 6:09 am
by Balthazar
Thanks :P Now I seem to become a little more smart! I know, that i will never be a good programmer, so i just want to realise one of my game ideas as easy as possible :P

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 6:16 am
by milipili
You just need practice. And you will see it will be easier and easier. It is like martial art. Simplicity Is Complexity Itself :)

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 6:26 am
by xpoy
same as zuzuf, +/- not working /:^[

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 6:41 am
by Balthazar
My bad :P The right Key is PgUP/PgDown to zoom

P.S. I don`t have enough time to practice - that`s the problem. I prefer to pay someone who know how to do it :P

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 7:48 am
by milipili
No problem. I can create a PayPal account if needed :D
But you have not the same satisfaction ^^

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 7:49 am
by zuzuf
time is relative ... I started TA3D when I was in "classe préparatoire" (2 years during which you're meant to work all the time ...) :P

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 7:58 am
by zuzuf
Milipili : it seems like we're synchronized :P, posting twice one after the other nearly in the same minute :P

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 8:24 am
by Balthazar
milipili wrote:No problem. I can create a PayPal account if needed :D
But you have not the same satisfaction ^^
Well, i doubt that I`ll get satisfaction without reaching the goal any way.

P.S. I`m starting to collect money :P

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 12:04 pm
by milipili
zuzuf wrote:Milipili : it seems like we're synchronized :P, posting twice one after the other nearly in the same minute :P
That's what we call "Team work" :D

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 12:09 pm
by milipili
Balthazar wrote:P.S. I`m starting to collect money :P
Good good :p

Actually, that's why we started the Yuni Framework. To provide high level and efficient routines to developers, without taking care of low level code (and actually, nearly of the code itself). You might be interressed in it when it will be more mature.

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 12:24 pm
by zuzuf
hm maybe Yuni is a bit complicated for beginners ? I mean using all C++ stuffs in your first game may be a bit difficult :?

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 1:17 pm
by milipili
The yuni internals is obviously for advanced C++ programmers only. However its API aims to be easy to use for developer with basic knowledge in C++.
Yuni still needs a lot of improvements, but the most simple way to achieve this goal is that you look at the existing samples :
http://trac.libyuni.org/browser/trunk/src/samples

Any feedback will be highly appreciated, especially if you are not a C++ jedi master ^^. If a sample seems too complicated, it must be improved/replaced.

Re: Question for experienced programmer

Posted: Thu Jul 09, 2009 7:03 pm
by xpoy
Will tank update to 0.6 :P

Re: Question for experienced programmer

Posted: Fri Jul 10, 2009 8:31 am
by Balthazar
xpoy wrote:Will tank update to 0.6 :P
I doubt that it will :P
milipili wrote: The yuni internals is obviously for advanced C++ programmers only. However its API aims to be easy to use for developer with basic knowledge in C++.
Yuni still needs a lot of improvements, but the most simple way to achieve this goal is that you look at the existing samples :
http://trac.libyuni.org/browser/trunk/src/samples
Is there any documentation?

Re: Question for experienced programmer

Posted: Fri Jul 10, 2009 12:01 pm
by zuzuf
don't be so sure, TA3D wasn't meant to reach version 0.1.0 :wink: first versions were just a test.

Re: Question for experienced programmer

Posted: Fri Jul 10, 2009 1:52 pm
by milipili
Balthazar wrote:Is there any documentation?
Doxygen only. We will write an user Guide when the API will be more stable. And we will make a real website too ^^. But for now on, we have some more useful tasks to do. Such as fixing some bugs (especially Yuni::String used by TA3D, fixing compilation for FreeBSD/Solaris, the doxygen itself...) and to begin to write Yuni::Gfx::Canvas, which will be the base for a good part of the GUI. The Lua script should be really working soon.
(http://libyuni.org/documentation/doxyge ... /dirs.html)

But except for team members and TA3D, if the library is used by other people, may be we should reconsider.

Re: Question for experienced programmer

Posted: Wed Jul 15, 2009 9:38 am
by Loom
milipili wrote:The yuni internals is obviously for advanced C++ programmers only. However its API aims to be easy to use for developer with basic knowledge in C++.
Any feedback will be highly appreciated, especially if you are not a C++ jedi master ^^. If a sample seems too complicated, it must be improved/replaced.
I'd go further than that and claim that if there is _any_ feature that a beginner cannot use (I do not mean understanding how it works, just use it), it means Yuni's design will have failed on that particular point. Of course, just like any other library, Yuni will require acclimatation but the purpose is to have a very fast learning curve even for very powerful features.

Re: Question for experienced programmer

Posted: Wed Jul 15, 2009 5:42 pm
by xpoy
well, for used adv features in eazy ways, a very big features will be packed, that will make a door, if know how the pack work, you enter door, or just outside of expert users. This the bad hand, the most good is beginner and travellers will have a good feel.
But for learn fast, there are some other measures can do this.
At first, know what's the users, that mean what the user used (custom),
and do the work in that style.
make some common examples (Frameworks)
a step by step user level, I mean, give diffrent call mothed for beginner/ veteran / master...

Re: Question for experienced programmer

Posted: Thu Jul 16, 2009 4:01 pm
by Loom
I am not sure I understood everything you just wrote, but I will try to elaborate anyway.
Many libraries seem to think that offering powerful features requires providing complicated, illegible interface, with many-parametered functions.
Some also seem to think that offering an easy-to-learn interface requires having next to no choice in configuration.

For (a rather stupid) example, the naive ones would offer to sort a list with something like this:

Code: Select all

void sort(int* list, unsigned short size);
There would not be much to be done with it, but it is clearly easy to understand and use.

The "elite" ones would offer something like this:

Code: Select all

ResultFlags sort(void* list, size_t eltSize, unsigned short size, SortingAlgorithm algo, ComparisonDelegate compare, Logger logs) throw;
They would think it necessary to be able to customize everything, to choose which algorithm to use for sorting, to be able to customize how elements should be compared, to have a detailed structure for storing errors, to throw an exception to be caught by users, to write a message to the logs, etc...
(forgive the exaggeration, it is only for purpose of the demonstration, a more realistic example can be found here).
This approach is praiseworthy for its completeness but it excludes any use by beginners who would be lost in possibilities and would never get anything done.

What we have in mind in Yuni is to let the user choose whether he wants powerful features (and which ones) or the default easy-to-use behaviour.
If you want to use all the default options to simply sort the damned list, you can. If you want to configure everything, you can.
And the best part of it is that this configuration will take place at compile time, so it will not impact performance in any way.
The downside (yes there is one) is that Yuni's code will look awful because of templates:

Code: Select all

template<class ComparisonDelegate,
             template<typename T, template<typename ELEM, typename = std::allocator<ELEM> > class CONT> class SortingAlgorithm = QuickSort>
class Sorter
{
public:
	template <typename T,
                      template <typename ELEM, typename> class CONT>
	static void operator()(CONT& list)
	{
		SortingAlgorithm<T, CONT<T> > sorter;
		sorter(list);
	}
};
This sample is not complete (or even correct) but you get my point...
Asking for users to understand this would be stupid and elitist.
But if done correctly, using it with default values would really be up to anyone:

Code: Select all

std::vector<int> myList;
sort(myList);
And even advanced uses would actually be quite accessible:

Code: Select all

std::vector<MyClass> mylist;
Sorter<myComparer<MyClass>, mySortingAlgorithm> sort;
sort(mylist);
I hope this makes things a bit clearer (and not worse) on what we wish to do.

Re: Question for experienced programmer

Posted: Thu Jul 16, 2009 7:19 pm
by milipili
Behind scene, we intend to use all features provided by the C++ language. Of course that includes template metaprogramming, because it offers (when well used) user-friendly and highly extensible APIs with very low performance penalty at runtime. Yuni uses wherever it is possible a Policy-based design, to let the user adapt the behavior according the real needs. I agree, the user rarely knows what it is good for him, and anyway he does not want to know.

It requires a good user documentation, but this is also true for any other project. In a first time, we're trying to respect this level of difficulty for the samples, from the most obvious/wanted use to the most complicated one. Then, we will see for a complete documentation. A good sample is often the best documentation, like a picture is worth a thousand words.

Re: Question for experienced programmer

Posted: Fri Jul 17, 2009 7:18 pm
by xpoy
It requires a good user documentation, but this is also true for any other project. In a first time, we're trying to respect this level of difficulty for the samples, from the most obvious/wanted use to the most complicated one. Then, we will see for a complete documentation. A good sample is often the best documentation, like a picture is worth a thousand words.

agree with a steers
And for sample, there are a useful study measures named control variables, that every times only all are know except that one researched. Associate to sample, what want sample, just that one, and except this one, all other things users already know that

Re: Question for experienced programmer

Posted: Sat Jul 25, 2009 5:47 pm
by zuzuf
concerning sorting algorithm, I wrote a C++ implementation of radix sort some time ago, maybe some one is interested.