Archived

This topic is now archived and is closed to further replies.

Locking FPS part III kinda...

This topic is 6359 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I''m gonna go to the mental ward soon...see OK--I''m kust moving a 2D box back and forth across the screen. It works fine if I dont multiply the velocity by the passed time. When I do that it goes nuts. Here''s the code for the 2 functions that are sending me to the looney bin:
    
void TestTimer(int FPS, TIMER_PTR timer)
{
	timer->FPS=FPS;

	if (QueryPerformanceFrequency((LARGE_INTEGER*) &timer->prfm_cnt)) {

		timer->pcount_flag=TRUE;
	//	timer->t_count=timer->prfm_cnt/timer->FPS;

		QueryPerformanceCounter((LARGE_INTEGER*) &timer->n_time);
		timer->t_scale=(float)1.0/timer->prfm_cnt;
	}

	else {
		timer->pcount_flag=FALSE;
		timer->n_time=timeGetTime();
		timer->t_scale=0.001;
		timer->t_count=timer->FPS;

	}

	timer->pframe=timer->p_time=timer->n_time;

void GetTheTime(TIMER_PTR timer)
{

if (timer->pcount_flag) 
	
	QueryPerformanceCounter((LARGE_INTEGER *) &timer->c_time); 
	
	else 
		timer->c_time=timeGetTime(); 

	time=(timer->c_time-timer->p_time)*timer->t_scale;

	timer->p_time=timer->c_time;




}


    
I call TestTimer during the init, and then I do this: 1. GetTime 2. Update Location of Box sprite->area.left=(sprite->area.left+(sprite->velocity*sprite->X_Motion*time)); sprite->area.right=(sprite->area.right+(sprite->velocity*sprite->X_Motion*time)); 3. Blit, Flip, and start back at 1 If I remove the time multiplication it works fine-otherwise the box just sits there, or moves all eratic(this is only when I multiply t_scale by a number, say 100). Any clues? BTW area is a RECT structure inside a sprite stucture.

Share this post


Link to post
Share on other sites
Well to start it depends on wheather your system is using QueryPerformanceTimer or timeGetTime. QueryPerformance timer will return the time in tick which is different for each system use QueryPerformanceFrequency to find out how many ticks per millisecond there are... On my PIII 533Mhz machine there are 1193 ticks per millisecond. Yup per MILLISECOND. It''s a much better timer system then GetTickCount or timeGetTime, but you''ll have to compensate.

What I''m guessing is your running on a pentium? Which mean you''ll be using the performance timer, whcih means in 1 second you''ll be multiplying your xmotion by 1193000 which is ridiculous! That''s why it''ll go crazy!

So when multiplying your x position, you need to check which timer your using, if your using Performance Timer you need to divide it by TicksPerMS which is returned by QueryPerformanceFrequency, that''d give you milliseconds, then you could divide it further by a speed constant (Or multiply by a fraction or percentage) to get your movement.

Umm... also I probably wouldn''t use the multiply by time thing. Is this your foundation learning for a future game? Well I''d create a struct or just a bunch of variables if your really newbie like x,y,colour(r,g,b), and LastUpdateTime. So those variables would all start 0.

So then in your loop you''d check if CurrentTime - LastUpdateTime is greater than let''s say 16ms. If it is then update the pos'' and colour. So when your updating the x,y and r,g,b variable you can just play around, try all sorts of stuff for moving it around, make it bounce around the screen or move in a circle etc.. But once you''ve got some variables that always determine where and how the object is painted, you can put in any kind of code you want to move it around or change it''s attributes. When you''ve got a hard-coded behavior it doesn''t allow for much adaptation aside from re-writing it.
Hope this helped some!
See ya,
Ben

Share this post


Link to post
Share on other sites
OK I think my time formula is correct-I think the problem is this: when I pass 0.7 into my RECT structure it converts it to 0. How can you make a rect structure take a double or a float?

Share this post


Link to post
Share on other sites
2 Things-My machine is a PIII 600 MHz, so it''s using the PerformanceCounter. I can''t create my "own" RECT structure because the RECT structure is used by DDraw to perform the blitting to the surface. Even if I was just using coordinates I still need a way to convert 1.5 to 2 so that it will work in the RECT structure for DDRAW. Any suggestions?

Share this post


Link to post
Share on other sites
Keep track of the "lost" movement for each object. Instead of trying to move 0.7 pixels move zero pixels, and in the next frame you would have 1.7 in your buffer, and then you would move 1 pixel and keep 0.7 in the buffer.

Did this make any sense?

/CMN

Share this post


Link to post
Share on other sites
How about using fixed point math. Count movement in 1/65535 of a pixel and shift ( value>>16 ) when an integer is needed. Float conversion is a waste of CPU.

Share this post


Link to post
Share on other sites
OK I got it working. I added this:
sprite->X_Position=sprite->X_Position+(sprite->velocity*sprite->X_Motion*time);

X_Position is a double that keeps track of, well..X Postion

Then I fill in my RECT using X_Position.

I doesn't seem to run as smooth now-is that normal-trade off smoothness for accuracy or am I still doing something wrong?

Every pass through the main game loop looks like this:

1. Blit The Background to the Secondary Surface
2. Check The Time
3. Update Square's Location based on time passed
4. Blit the Square to the Secondary Surface
5. Check to see if its time to flip the surfaces

This way I am locking the FPS, and basing movement on real time, correct?? One wierd thing though-If I lock the FPS at 30-the code only runs at like 18 FPS, If I Lock it at 200 FPS, it runs at 75 FPS. Is this normal? Thanks


Edited by - Chipcrap on July 15, 2000 2:06:38 PM

Share this post


Link to post
Share on other sites
There is another way to look at this. it's not the only solution for fps. You can use this code (link the project w/ winmm.lib)
            
#include <Mmsystem.h>
.
.
.
// Global vars

DWORD lasttime,currenttime=timeGetTime();
float timeoffset,fps;
.
.
.
// Just before drawing

// be careful; in the first frame,
// it doesn't tell the right fps

// the solution is to move the code

// to the end of the drawing proc,
// but then you lose the first frame's fps


lasttime=currenttime;
currenttime=timeGetTime();
timeoffset=(float)(currenttime-lasttime);
fps=1.0f/(timeoffset/1000.0f);
.
.
.

You can update the code by this equation.

"Everything is relative." -- Even in the world of computers.

Edited by - Ionut Costica on July 15, 2000 10:06:32 PM

Share this post


Link to post
Share on other sites