#11710 - RaBBi - Thu Oct 16, 2003 12:01 pm
Hi,
I would like to know what are the common uses of these two interruptions.
For the moment, I only use VBLank to copy in OAM.
But I read that some effects requires HBlank (like "raster" >> I don't know what it means, or to display more than 128 sprites).
I'd like to know what is fundamentaly different between them, more than the time execution ^^
Thanks ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^
#11715 - niltsair - Thu Oct 16, 2003 4:21 pm
VBlank interupt occurs everytime the screen refresh reach line 160.
HBlank interupt occurs everytime the screen refresh reach column 240.
The screen refresh itself from left to right then jump one line down. (columns first, then line)
VBlank is usually used to:
1. Keep track of time by creating timers
2. Refresh the content of the screen so no flicker occurs(you have 68lines to refresh content)
HBlank is usually used to:
1. Do some visual effects that change various register content so on the next line, the content is different. Example : At the end of every line, you change the value of horizontal scrolling, to create a wave like effect.
2. Get more out of the limited video memory. Every 8lines, you could re-use the same sprite by just moving them again. Or you could change the content of tile memory to get more tiles.
_________________
-Inside every large program is a small program struggling to get out. (Hoare's Law of Large Programs)
-The man who can smile when things go wrong has thought of someone he can blame it on. (Nixon's Theorem)
#11716 - RaBBi - Thu Oct 16, 2003 5:39 pm
Thanks
it's more clear ^^
But, as frenchy, there are some terms that I don't know :
- "flicker"
And why 68 lines?
And, I think that I'm wrong but, I understood that there are 160 HBlank during one VBlank.
Am I wrong?
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^
#11717 - niltsair - Thu Oct 16, 2003 6:29 pm
Flicker is a hard to translate, but is roughly equivalent to 'scintillement'. It happens when some part of the screen quickly change to something and then some part of it is wrong.
The VBlank is use to prevent things like this:
Say you're background is a solid black then you decided to change it to blue. But you do so while the screen refresh is in the midle of the screen. For 1 screen, you'll quickly see half of a screen black and the other blue. The next screen refresh, your screen is all blue.
68 lines is because the GBA goes trhough refreshing 228lines. Only 160 of those are visible, which means that from 160-228 you're free to do what you want without it having any ill effect on the display.
A HBlank interupt occurs once per line. I'm not certain if they still occurs on the lines that are offscreen. If not, 160 per 1VBlank. If yes, then 228 per 1 VBlank.
_________________
-Inside every large program is a small program struggling to get out. (Hoare's Law of Large Programs)
-The man who can smile when things go wrong has thought of someone he can blame it on. (Nixon's Theorem)
#11745 - RaBBi - Fri Oct 17, 2003 8:02 pm
Really clear now !
I thank you ^^
But how can I know (detect) that I'm between 160-228 ?
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^
#11746 - niltsair - Fri Oct 17, 2003 8:13 pm
4 Ways...
1- Read the value of the VCount register (VCOUNT )
2- Read the value of the Screen status register (DISPSTAT)
3- Enable interupt to occurs on a VBlank. The interupt fucntion will get called everytime scanline = 160.
4- Enable VCount interupt, you can tell the interupt to happen at a particular scanline.
Usually, you'll want to do your processing during in a VBlank interupt (3). The WaitForVBlank method you've been using actually just loop untill the DispStat indicate that you've reached scanline 160.
For more info on the register you'll have to look at the GBATEK document or Cowbyte that are available under the www.gbadev.org -->doc-->general.
_________________
-Inside every large program is a small program struggling to get out. (Hoare's Law of Large Programs)
-The man who can smile when things go wrong has thought of someone he can blame it on. (Nixon's Theorem)
#11763 - RaBBi - Sat Oct 18, 2003 9:44 am
Oki, I knew VBlank Interrupt (and I used to copy OAM yet), but I think I'll use VCount Interrupt to know how many scanlines are refreshed.
Can I do some operations like this ? :
- Enable VBlank Interrupt,
- When VBlank is triggered, Enable VCount Interrupt, g_Scanlines = 160,
- When VCount is triggered, g_Scanlines++,
- When g_Scanlines = 228, reset g_Scanlines to 160, Disable VCount interrupt.
Is that a good way to do some stuff between 160th and 228th scanlines? ^^
_________________
Sorry for my poor english, but it would be worst for you to understand me if I speak in my native language, French ^^
#11765 - Gopher - Sat Oct 18, 2003 4:37 pm
Quote: |
- Enable VBlank Interrupt,
- When VBlank is triggered, Enable VCount Interrupt, g_Scanlines = 160,
- When VCount is triggered, g_Scanlines++,
- When g_Scanlines = 228, reset g_Scanlines to 160, Disable VCount interrupt.
|
This would work, but is more complicated than needed.
Triggering the code on the VBlank interrupt is definately the way to go, but then basicly you're making a copy of VCount and incrementing it whenever VCount is incremented. Instead of looping on your own copy, just loop while the actual VCount register is < 228 and it'll work just as well.
I guess you were trying to avoid waiting on the register, but the comment that you should use interrupts instead of waiting just refered to the empty wait loop you would have in a WaitVBlank() function
This would be bad
Quote: |
while(REG_VCOUNT<228)
{
//do nothing
}
|
but as long as you're doing something inside the loop, it's fine.
_________________
"Only two things are infinite: the universe, and human stupidity. The first is debatable." -Albert Einstein
#11779 - shaktool - Sat Oct 18, 2003 8:34 pm
Hmmm... it seems there are many things you can do with HBlank and VBlank...
I haven't tested this, but isn't it possible to make a full 15bit color background by changing the color palette between each row? There are 240 pixels horizontally, and 256 colors, so each pixel could correspond to it's own color in that row, and then in the next row the color palette could be different so each of the pixels in that row could have it's own color too. In this way, none of the pixels in the background would be forced to share colors with any of the others...(actually, there are 38400 pixels and 32768 possible colors, so a few thousand would kinda have to share, but...)
The only data that would have to be altered dynamically are the colors in the color palette. Is there enough time during HBlank to change 240 16-bit values?
Edit: Yeah, I realize that Modes 3 and 5 are alternative options to full 15-bit color... but they have disadvantages...
#11780 - sajiimori - Sat Oct 18, 2003 8:46 pm
No, there is not enough time to modify the entire palette. There are only 228 cpu cycles per hblank.
#11782 - tepples - Sat Oct 18, 2003 9:33 pm
It takes 4 cycles to copy 2 bytes from EWRAM to VRAM. Therefore, copying 240 colors would take 480 cycles, which would overflow Hblank.
However, mid-scanline writes to palette memory do in fact work. Thus, by the time the RAMDAC gets to the beginning of the line, the palette copy has reached the middle of the line, and by the time the RAMDAC gets to the middle, the palette copy has reached the end of the line.
But still, such an Atari 2600 style approach to generating the screen wouldn't have any advantages over mode 3.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#12193 - yaustar - Mon Nov 03, 2003 3:37 pm
can someone give me a code snippet to use an interupt for the CopyOAM function as aI dont understand how they are used code wise.
_________________
[Blog] [Portfolio]