Sign in to follow this  
PcChip

I'm about to throw my computer out the window

Recommended Posts

PcChip    122
this is so frustrating. First I was getting a divide by zero error, when that can't be possible becuase I check ElapsedTime before I divide by it. Now I'm getting some access violation or somethign on the sprintf line. WHY?! THIS IS SO FRUSTRATING!! Any help would be much appreciated, thanks! /*====================== Calculate Frame Time ======================*/ FrameTime.CurrentValue = GetTickCount(); FrameTime.ElapsedTime = FrameTime.CurrentValue - FrameTime.LastValue; FrameTime.LastValue = FrameTime.CurrentValue; /*==================================================================*/ char data[256] = ""; if(FrameTime.ElapsedTime != 0) { fps = 1000.0 / FrameTime.ElapsedTime; } sprintf(data,"FrameTime.ElapsedTime = %n",FrameTime.ElapsedTime); Draw_Text_GDI(data, 100, 100, RGB565(31,63,31), backbuffer);

Share this post


Link to post
Share on other sites
ApochPiQ    23065
You need to check the documentation for sprintf. %n does not do what you think it does - it expects a pointer to an integer where it can store the number of characters written. FrameTime.ElapsedTime is not a pointer to an integer, so sprintf() writes to (essentially) random memory, and you get an access violation.

Share this post


Link to post
Share on other sites
PcChip    122
Thanks alot, I got that part fixed!

now the ElapsedTime alternates between 0 and 15 ms

any clue why it does that?

monitor is set at 100hz and i think the vsync is on

... so when i try to calculate and print the FPS i get very strange numbers
maybe i'm doing that wrong as well?

Share this post


Link to post
Share on other sites
oliii    2196
possibly, gettickcount as a resolution of 15 ms.

15ms is 66 hz.

if frame rate is locked to 100 hz (10 ms), then one of 1 frame out of 3 will have 0 ms. Or something like that.

Share this post


Link to post
Share on other sites
PcChip    122
so then i need to be using something else than GetTickCount() ...

because i'm planning on having time-based movement, instead of frame based, that way it will run the same speed regardless of what framerate it's running at on different people's computers, and i guess the 15ms lower limit on GetTickCount() isn't low enough for me

I've heard about QueryPerformanceCounter or something like that, would that be a better option in my case ?

Share this post


Link to post
Share on other sites
skillfreak    160
you certainly will get more precision with high performance timers. And, with your initial case, be sure to set FrameTime.LastValue to some val other than 0 on init(), you should be able to rip that if out of there afterward.

Share this post


Link to post
Share on other sites
chad_420    290
Queryperformance counter is exactly what you need. And fortunatly you can damn near plug it in place of timeGetTime with only a few minor changes.

Share this post


Link to post
Share on other sites
PcChip    122
a problem and a question:


struct sFrameTime
{
LARGE_INTEGER LastValue;
LARGE_INTEGER CurrentValue;
LARGE_INTEGER TicksPerSecond;
float ElapsedTime;
} FrameTime;

//once per frame
/*====================== Calculate Frame Time ======================*/
QueryPerformanceCounter(&FrameTime.CurrentValue);
FrameTime.ElapsedTime=FrameTime.CurrentValue.QuadPart-FrameTime.LastValue.QuadPart;
FrameTime.LastValue =FrameTime.CurrentValue;
/*==================================================================*/


When i print out the value of FrameTime.ElapstedTime it's ALWAYS 0
I know the counters are working because i'm printing those out too


Now the question: what if in the middle of your game, the 'performance counter' wraps around from max to min, that would severly mess up your game, how do commercial games get around this?

Share this post


Link to post
Share on other sites
Graham    166
You need to divide ElapsedTime by Queryperfomancefrequency() to get seconds. Also it would probably take years for the LARGE_INTEGER to overflow.

Share this post


Link to post
Share on other sites
PcChip    122
yes i understand, however at this point i don't want seconds, i simply want to see the number of ticks since the last frame. I keep getting 0 so something is wrong. Once i fix that i can move on to displaying FPS

Share this post


Link to post
Share on other sites
Halsafar    205
Visit this thread from VbForums. I just told someone else in a thread from yesterday about this. Its an old thread that I started almost a year ago and someone bumped it asking for a QueryPerformanceTimer class.

The download is near the bottom of the thread, feel free to download and use the class, credit me for your timer :) Actually a timer class is pretty standard, no sense in re-inventing the wheel, so enjoy.
http://vbforums.com/showthread.php?t=305885

Share this post


Link to post
Share on other sites
Graham    166
If you are using a really old computer then it may not support QueryPerformanceCounter, and in that case I think you would get 0. The reason that you divide by the perfancefrequency is because the counter will be different on different CPU's. So divide by the frequency then multiply by 1000 to get milliseconds.

Share this post


Link to post
Share on other sites
Xai    1848
// first, a minor change (this is not your problem of course:

struct sFrameTime
{
LARGE_INTEGER LastValue;
LARGE_INTEGER CurrentValue;
static LARGE_INTEGER TicksPerSecond; // don't store this PER SAMPLE, it never changes
float ElapsedTime;
} FrameTime;

// now a real change:

struct sFrameTime
{
LARGE_INTEGER LastValue;
LARGE_INTEGER CurrentValue;
static LARGE_INTEGER TicksPerSecond; // don't store this PER SAMPLE, it never changes
LARGE_INTEGER ElapsedTicks;
} FrameTime;

/*====================== Calculate Frame Time ======================*/
QueryPerformanceCounter(&FrameTime.CurrentValue);
FrameTime.ElapsedTicks.QuadPart=FrameTime.CurrentValue.QuadPart-FrameTime.LastValue.QuadPart;
FrameTime.LastValue =FrameTime.CurrentValue;
/*==================================================================*/

then see if the value is still zero.

Also, the REAL way to solve this kind of problem is easily done with a debugger, just break into the debugger and look and see if Current and Last are exactly the same before your subtraction, if so, the problem is higher up (or non-existent), if not, the problem is with your subtraction, assignment, or display ...

Share this post


Link to post
Share on other sites
PcChip    122
thanks dude I appreciate it, but the frustrating part is that i can't get my code working, does anyone have any idea why ElapsedTime is always coming out 0 ?

Share this post


Link to post
Share on other sites
Halsafar    205
Did you miss my post??
Download the class timer wrapper and compare it to your code to find your error. Simple as that.

Share this post


Link to post
Share on other sites
PcChip    122
xai - thanks a bunch, that fixed it
except for the static part, i now get:
game.obj : error LNK2001: unresolved external symbol "public: static union _LARGE_INTEGER sFrameTime::TicksPerSecond" (?TicksPerSecond@sFrameTime@@2T_LARGE_INTEGER@@A)


but it doesn't matter because there will only be one 'sample' as you put it, there is only one object of that struct


Halsafar - thanks for your time too, i appreciate it

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
Quote:
Original post by PcChip
xai - thanks a bunch, that fixed it
except for the static part, i now get:
game.obj : error LNK2001: unresolved external symbol "public: static union _LARGE_INTEGER sFrameTime::TicksPerSecond" (?TicksPerSecond@sFrameTime@@2T_LARGE_INTEGER@@A)


To fix this, in your header, have the structure as per usual:

struct sFrameTime
{
LARGE_INTEGER LastValue;
LARGE_INTEGER CurrentValue;
static LARGE_INTEGER TicksPerSecond; // don't store this PER SAMPLE, it never changes
float ElapsedTime;
} FrameTime;

In a source file, have:

#include "......"
LARGE_INTEGER sFrameTime::TicksPerSecond;


HTH

Share this post


Link to post
Share on other sites
MaulingMonkey    1730
Quote:
Original post by PcChip
actually that struct isn't in a header, it's in the main cpp file at the top


It should be in a header if you want to be able to use it in multiple cpp files.

In any case, in order to get the static variable to work, you simply need to also declare it seperately, like so:

struct A {
static B C;
};

B A::C;

You will get multiple definition errors if the "B A::C;" line is in a header included by multiple CPP files. Although I'd generally advise "struct A { ... };" to be in a header, not doing so shouldn't cause errors.

HTH

Share this post


Link to post
Share on other sites
PcChip    122
now I'm trying to find out the number of seconds that have elapsed:

FrameTime.Seconds = ((float)FrameTime.ElapsedTime.QuadPart /
(float)FrameTime.TicksPerSecond.QuadPart);

[FrameTime.Seconds is a float]

i keep getting all kinds of results, including some negatives :(
I've even looked at the code mentioned from that other thread and it's not helping me, what am I doing wrong ??

Share this post


Link to post
Share on other sites
PcChip    122
i keep getting all kinds of random numbers when i'm expecting to get like .01

i'm getting stuff like -294298428 and 4245981

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this