Welcome! Log In Create A New Profile

Advanced

wait and time code

Posted by durda_dan 
wait and time code
March 07, 2009 03:23PM
i don't know who has played my demo release of steadyhand. But one of the things i Really don't like is the wal collision. The screen goes black, Gives you text and has a Usleep,

if (cursorx >= 260 && cursorx <=420 && cursory >= 300 && cursory <=400){ // landingpad bottom
                VIDEO_ClearFrameBuffer(rmode,xfb,COLOR_BLACK);
	errorcountlv4 ++;
	printf("you touched the edge");
	usleep(5000000);
}
I hate the Usleep, It makes it much too hard to Position the cursor after a mess up.

Would there be a way to do something like this *type in pseudocode*

if cursor on the wall{
print "you touched a wall"
wait half a second and then return the words disappear.
}

But during that whole time the you would have control of the cursor.


andother question
Instead of using an error tracking variable. how would i use a code to have a timer that would keep track of time outside of the walls. in miliseconds/seconds/minutes?
Re: wait and time code
March 07, 2009 07:09PM
The general psuedocodeish way to do it would be to set a counter to 5000ms or whatever unit of time you can count by, and then in your game loop
if (counter>0){
currentTime = getTimeNowSomehow()
counter = counter - (currentTime - lastTime)
lastTime = currentTime
/*stuff that you want to handle, eg. input*/
}else{
/*normalish game code*/
}

This might not be the best way to do it, but that's how I would do it because then you aren't sleeping. Unfortunately, I don't actually know the functions required to get the current time.
Re: wait and time code
March 08, 2009 05:16PM
Sleeping is always a bad solution as other components of your game still may need to update its states (e.g. position of a sprite, visibility of a message, ...)

Timing on the Wii is kind of pain in the ass. At least, if you need a timer with a high resolution. The function clock_t clock ( void ); doesn't work for me with devkitppc (always returning -1). You can still use time_t time ( time_t * timer ); though, if you are fine with getting the time in seconds. In most cases you will want to get the time in a higher resolution.

I figured that some homebrew applications use the display refresh rate to build a custom timer, e.g:
...
f32 current_time = 0.0f;
f32 delta_t = 1.0f/60.0f; //or 1/50 depending on the video mode
...
while(running) {
 ....
  // Wait for the next frame
  VIDEO_WaitVSync();
  current_time += delta_t;
}
Re: wait and time code
March 08, 2009 07:54PM
Yeah, it is fairly common to use framerate based timers in simple games. But they are only a good option if you honestly think that the framerate can be archived. And you really need to have an upper limit on the framerate, as old games exampliefies what happens otherwise, they are unplayable!
Re: wait and time code
March 08, 2009 08:00PM
There's a high-res millisecond timer here:
Header
Code

Or, if you're more into C++...
/****************************************************************************
* tmbinc msec timer
****************************************************************************/
#ifdef HW_RVL
#define TB_CLOCK  60750000 /* WII */
#else
#define TB_CLOCK  40500000
#endif

struct MillisecondTimer
{
	MillisecondTimer()
	{
		Update();
	}

	void Update()
	{
		{u32 u; do {
			asm volatile ("mftbu %0" : "=r" (u));
			asm volatile ("mftb %0" : "=r" (tm.l));
			asm volatile ("mftbu %0" : "=r" (tm.u));
		} while (u != (tm.u)); }
	}

	u32 operator -(MillisecondTimer& timer)
	{
		tb_t* end = &tm;
		tb_t* start = &timer.tm;
		u32 upper;
		u32 lower;
		upper = end->u - start->u;
		if (start->l > end->l)
			upper--;
		lower = end->l - start->l;
		return ((upper * ((unsigned long) 0x80000000 / (TB_CLOCK / 2000))) +
			(lower / (TB_CLOCK / 1000)));
	}

protected:
	struct tb_t
	{
		u32 l;
		u32 u;
	};

	tb_t tm;
};

...

// Usage before a main loop...
	MillisecondTimer start;
	MillisecondTimer current;
	while (true) {
		current.Update();
		u32 ticks = current - start;
		// ticks now holds the number of milliseconds since the start of your app/loop.

		// Draw stuff like normal, etc...
	}

Quote
henke37
And you really need to have an upper limit on the framerate, as old games exampliefies what happens otherwise, they are unplayable!
Hah, is there any Gamecube homebrew that runs really fast on the Wii because of that? :P



Edited 4 time(s). Last edit at 03/08/2009 08:04PM by AerialX.
Re: wait and time code
March 09, 2009 10:40AM
I think the thing above is already implemented in libogc: just use gettime() to get the elapsed ticks since boot (in microsecond) , diff_usec() to calculate the difference between 2 values (this take timer overflow in account) and usleep() to wait a specific amount of microseconds.

If you want to do other stuff while waiting, use multithreading..

Quote

Hah, is there any Gamecube homebrew that runs really fast on the Wii because of that
framerate is the same on all consoles, it's (approximately) 1/60s for NTSC and PAL60 (480i/480p) and 1/50s for PAL50 (576i)
However, even if using the video interrupt is good to synchronize your code (since you usually want it to refresh what appears on screen) , it is not practical for exact time measurement. For the record, I "measured" that in 60Hz modes, VSYNC occurs approximately each 16715 us (and not 16666.66 as you would think) and 19667 us in 50 Hz mode.

So, the most accurate way is to use the internal Timer, which the above functions already do.



Edited 2 time(s). Last edit at 03/09/2009 10:42AM by ekeeke.
Re: wait and time code
March 09, 2009 03:01PM
Yeah, it is the same on all consoles, that have the same framerate. Guess what? Not all consoles are using 60 Hz at all times. Some games did not handle this very well.

At least now we have PAL60 to solve that issue. But then again, there is games that explicitly refuse to run in PAL60, they are scared of people paying for their game and using it in another place.



Edited 1 time(s). Last edit at 03/09/2009 03:03PM by henke37.
Re: wait and time code
March 09, 2009 04:58PM
Quote
ekeeke
I think the thing above is already implemented in libogc: just use gettime() to get the elapsed ticks since boot (in microsecond) , diff_usec() to calculate the difference between 2 values (this take timer overflow in account) and usleep() to wait a specific amount of microseconds.
Last time I tried gettime() it returned the time in ticks, but the value was only updated once a second >.>
(So it may have been in ms, but the precision was still 1s)

And yeah, VSync isn't that accurate for time-critical counters.

Quote
ekeeke
framerate is the same on all consoles, it's (approximately) 1/60s for NTSC and PAL60 (480i/480p) and 1/50s for PAL50 (576i)
I meant if there was any homebrew that didn't wait for a VSync and runs faster as a result.
Re: wait and time code
March 09, 2009 06:16PM
yeah, you're right, it returns a value in tick
diff_usec can be used to get the delta in microseconds between two tick values

apparently, tick frequency is 1/4 of the bus frequency, so using directly the ASM routines based on the Gamecube bus frequency value would result in faster timings, this was indeed the case in older versions of some emulators, where we were using Timer to synchronize frame emulation

However, most homebrew use libogc functions, which have been updated to use Wii frequency if required so there is no timing issue



Edited 1 time(s). Last edit at 03/09/2009 06:17PM by ekeeke.
Re: wait and time code
March 10, 2009 02:37AM
i tried
#include
time_t

but that didn't work.... it gave me a -4000000~0 time frame, when i activate it, and a -968371000~0 when i don't... i can't get it to work properly...

another question, How do i multithread, or jump to a different section of code for example pressing B to back a page in the menu??
Re: wait and time code
March 14, 2009 03:11AM
@AerialX

Just wanted to say thanks for the C++ version, I've been looking for an accurate Wii timer. Other methods I've tried have been inconsistent. Actually the whole thread has been very informative, cheers.


@durda_dan

You will want to use current time - previous time, then * 0.001 to get an actual frame time. Then replace previous time with current time, ready for the next frame.
Now, if you have say "static float autoOff = 5.0;" you can on each frame subtract the frame time until autoOff <= 0.0 and then do your thing (remember to reset autoOff to 5.0 when your counter reaches zero, or when you apply it next time).
Re: wait and time code
March 15, 2009 03:55AM
This is the timer class I use.

#include ogc/lwp_watchdog.h>

class Timer{
	double Then;
Timer::Timer()
{
	Then = ticks_to_millisecs(gettime()) / 1000.0;
}
double Timer::TimePassed()
{
	double diff = ticks_to_millisecs(gettime())/ 1000.0 - Then;
	Then = ticks_to_millisecs(gettime())/ 1000.0;
	return diff;

}

};

It will tell you the difference in time since the last time you called it, with a precision of 0.001



Edited 1 time(s). Last edit at 03/15/2009 03:55AM by agoaj.
Re: wait and time code
March 30, 2009 03:54AM
Is there a function that can return the current scanline?



Edited 1 time(s). Last edit at 03/30/2009 03:56AM by daniel_c_w.
Sorry, only registered users may post in this forum.

Click here to login