how to slow down the main loop?

Discuss the development of software, tools, libraries and anything else that helps make ps2dev happen.

Moderators: cheriff, Herben

Post Reply
User avatar
kouky
Posts: 48
Joined: Tue Sep 25, 2007 5:38 am
Location: London
Contact:

how to slow down the main loop?

Post by kouky »

The main loop fo my program is looking something like this:

Code: Select all

	while (1)
	{

        renderOneFrame();

       gotoNextFrame();

	/* execute render queue */
	gsKit_queue_exec(gsGlobal);

        /* vsync and flip buffer */
        gsKit_sync_flip(gsGlobal);

	}
It's about playing back custom video files.
As I'm running on PAL system and settings, I did expected this loop to be executed in 1/25 seconds since there is a "vsync" on it, but it's running much faster!

How can I prevent my main loop not to be done in less than 1/25 seconds?

Thanks !
softwares for artists on video game systems - http://www.pikilipita.com
User avatar
Lukasz
Posts: 248
Joined: Mon Jan 19, 2004 8:37 pm
Location: Denmark
Contact:

Post by Lukasz »

If you are running your application in FRAME mode (low horizontal resolution, eg. 640x256 or 320x256) you are not using interlace mode and your program will infact be running at 50 FPS in PAL mode.

If you are using FIELD and interlace mode, which takes 2 vsync to display a frame (even/odd lines), you actually need to wait for vsync twice to get 25 FPS.

I can see in the gsKit source (gsCore.c) that gsKit_sync_flip(..) just waits for gsKit_vsync() once and that gsKit_vsync() waits using a while loop. This is bad design for interlace mode, because you need to wait for vsync twice, you are wasting 1 frame of computation in a while loop, since you need to do:

Code: Select all

   gsKit_vsync();
   // Doing nothing for 1 frame
   gsKit_sync_flip(gsGlobal); 
To get around this, you need to register a vsync interrupt handler, which gets called every time there is a vsync. For this function you have atleast two options.

1) Make this function flip the buffers when it gets called, once for non-interlace mode and twice for interlace mode. This method requires additional code when you call the buffer flip function, as you can only flip if there is an already displayed (on screen) buffer available. It could happen that your application is so fast in rendering, that you are actually able to render more FPS than vsyncs pr. second (VPS), however only VPS frames are displayed on screen, so you need to be careful about overwriting buffers. The other scenario is that your code does not render fast enough and the buffer is displayed while rendering, then you get what is known as tearing http://en.wikipedia.org/wiki/Page_tearing

2) Make this function count how many vsyncs occurred since the last buffer flip and make your gsKit_sync_flip(gsGlobal) wait for the this value to become 1 for non-interlace and 2 for interlace.

These changes of course need to be made to the gsKit source. However the quick and not so great solution is just to call gsKit_vsync() just before calling gsKit_sync_flip, if your main loop takes less time than 1 vsync, which appears to be the case.
Post Reply