#6139 - niltsair - Sun May 18, 2003 4:59 am
Have been wondering about this one for some time.
with this line :
while((volatile u16)REG_VCOUNT != 160){}
Does each evaluation of the predicate takes less than 1 scanline. I think so, but i wasn't sure and so was wondering if it could occurs that we miss line 160 and have to wait an entire screen refresh.
#6140 - wiz - Sun May 18, 2003 5:04 am
Hi there,
perhaps this is a solution if the scanline is missed:
while((volatile u16)REG_VCOUNT < 160){}
Good luck
#6142 - niltsair - Sun May 18, 2003 5:24 am
I don't have this problem, it's just something i was wondering about.
There's a problem with the solution you submited. The condition would return False if it was on the last scanlines and we would thus restart on scanline 1 soon afterward, not giving us enough time to do all of our screen's operations. So it would have to be more like :
while((volatile u16)REG_VCOUNT < 160 && (volatile u16)REG_VCOUNT > 165){}
But i doubt it is needed, i think the condition can be evaluated under 1 scanline without problem, i just wanted confirmation.
#6143 - sgeos - Sun May 18, 2003 5:40 am
Code: |
while((volatile u16)REG_VCOUNT != 160){}
while((volatile u16)REG_VCOUNT [b]<[/b] 160){} |
These do different things. The first one stalls unless the scanline is 160. The second stalls if the scanline is less than 160.
vblanks begins on scanline 160. There are problems with each of these if you assume that they do something without understanding what they actually do.
If you do something that takes less than once scanline, it will be done multiple times with the first bit of code above. It will be done many, many times with the second.
If you do something that takes less than the vblank, it will be done once with the first bit of code above. It will be done multiple times with the second.
If you want something do be done only once a frame, interrupts are the way to go. If you don't understand interrupts, then use the following:
Code: |
while((volatile u16)REG_VCOUNT == 160){}
while((volatile u16)REG_VCOUNT != 160){} |
That stalls if the scanline is 160. When the scanline is no longer 160, or if it was not 160 to begin with, then it will stall until the scanline is 160 again. You can remove the first loop if you are sure everything will take more than one scanline to complete.
If the first loop is left in, and your routine happens to take up the whole vblank and vdraw and finishes when the scanline is 160 again, then it will stall for a whole frame because it thinks that your routine took a very short time to complete.
I hope that wasn't worded in a really confusing manner.
-Brendan
#6152 - Link - Sun May 18, 2003 1:32 pm
But, what is VSync? And vblanks?
#6156 - SmileyDude - Sun May 18, 2003 3:22 pm
If all you are doing is waiting for the vblank, and the inside of the loop is empty, I think you're worrying too much about missing the vblank. REG_VCOUNT changes at the start of the line, and unless your compiler is spitting out crap code, there is no way that you're going to miss a particular line (in this case, 160) when doing nothing else.
Most likely, you are probally reading REG_VCOUNT many times in a single line -- in fact, this method wastes CPU time, and more importantly on the GBA, the battery. So, the possibility of missing when line 160 comes around is the least of your worries :)
_________________
dennis
#6160 - Quirky - Sun May 18, 2003 5:28 pm
And the best way is to use the bios interrupt for vblank - doing that fixed a lot of timing bugs I had due to "was it on the vbalnk/wasn't it?" problems.
#6163 - Link - Sun May 18, 2003 6:14 pm
Link wrote: |
But, what is VSync? And vblanks? |
up
#6170 - tepples - Sun May 18, 2003 8:54 pm
Link wrote: |
But, what is VSync? And vblanks? |
Those are explained in the various tutorials that the FAQ in the Beginners section links to, or even in a DirectDraw tutorial.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#6174 - Link - Sun May 18, 2003 10:33 pm
never i see it!
Anyway i use DirectX 8.1 and never seen it in SDK.
#6178 - tepples - Mon May 19, 2003 2:49 am
Link wrote: |
never i see it!
Anyway i use DirectX 8.1 and never seen it in SDK. |
Vblank, short for vertical blank, refers to the time between when the video hardware draws one frame and when it draws the next frame. The term "vsync" refers to waiting for the vertical blank before drawing something so that everything moves more smoothly.
I don't know about Direct3D 8, but DirectDraw 7 had DirectDraw7::WaitForVerticalBlank.
To wait for vblank on GBA, you can spin on VCOUNT:
Code: |
#define VCOUNT (*(volatile u16 *)0x04000006) /* 0-159: draw; 160-227 vblank */
void wait4vbl(void)
{
while(VCOUNT != 160) ;
while(VCOUNT != 161) ;
} |
Or you can save battery power by installing an ISR, or interrupt service routine, and then doing this:
Code: |
void wait4vbl(void)
{
asm volatile("mov r2, #0; swi 0x05" ::: "r0", "r1", "r2", "r3");
} |
(There are tons of examples in gbadev.org's sources section that demonstrate how to write and use an ISR.)
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#6193 - Link - Mon May 19, 2003 11:43 am
tnx tepples ;)