gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Few HBlank related questions

#34211 - identitycrisisuk - Sat Jan 15, 2005 6:11 pm

I made a new little demo last night (click nuproj.zip), I was quite impressed with it for a few hours work but there's some things that aren't quite right, which I think are because I don't fully understand what's going on when you allow HBlank interrupts. In that demo the top line always scrolls at the maximum speed, no matter what it should do given how far down the background is scrolled. Here's my interrupt enabling code:
Code:
REG_IRQ_HANDLER = IrqHandler;
REG_DISPSTAT = (1<<4);
REG_IE = (1<<1);
REG_IME = 1;

And here's my IrqHandler function (in a separate file):
Code:
void IrqHandler(void)
{
   int vpos = BGy+REG_VCOUNT;
   if((vpos < 32) || (vpos >= 224))
   {
      REG_BG0HOFS = BGx;
   }
   else
   {
      if((vpos < 64) || (vpos >= 192))
      {
         REG_BG0HOFS = BGx>>1;
      }
      else
      {
         if((vpos < 96) || (vpos >= 160))
         {
            REG_BG0HOFS = BGx>>2;
         }
         else
         {
            REG_BG0HOFS = BGx>>3;
         }
      }
   }
   REG_IF = REG_IF;
}

BGy is how much scrolled down my background is so by adding REG_VCOUNT to it I should get the true position a horizontal line relates to and how much the scroll register should be set to to give the right paralax effect (which is chosen in the following if statements). I'm thinking my problem might be that REG_VCOUNT does not necessarily hold the number of the horizontal blank that you are on at that exact point and that on the first HBlank it's some big number left over from the last time round maybe? What's the 'official' or best way to find out exactly what horizontal line you are drawing when you come to a HBlank interrupt?

I'm also getting funny little black artifacts when I run this on a GBA but not through VBA strangely enough. I don't know if that's because I'm doing too much work, the code's in C not ASM and it only really needs to change the horizontal scroll every 32 HBlanks (or thereabouts) not every single line.

Off topic, I'd also like to know how best to scale one number to another using just ints. I've seen a few threads talking about getting a constant value in fixed point and then multiplying, how would I do that practically? I want to take the ships y position (between 0 and 159<<8) and scale it to a number between 0 and 96, which is the maximum I can scroll a 256x256 background before the top of it will appear at the bottom if you get me. At the moment I'm just dividing the screen position of the ship by 2, which avoids artefacts but is missing a bit of the bottom, I really need to multiply by 0.6 or some equivalent technique.
_________________
Code:
CanIKickIt(YES_YOU_CAN);

#34217 - tepples - Sat Jan 15, 2005 6:29 pm

Writes to the scroll registers during hblank take effect on the line after the write. Always set up scanline 0 during vblank, and then start your hblank ISR updates or your hblank DMA at position 1.

To multiply approximately by 0.6, use fixed-point arithmetic. Multiply by 154 and divide by 256.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#34218 - identitycrisisuk - Sat Jan 15, 2005 6:56 pm

Thanks for the fixed point thing, I get that - implemented nice and easily.

So to do what I really want to do I'd either enable a VBlank interrupt and do what I want for line 0 there or just do it in my normal code loop after my wait for Vblank? And then in each HBlank interrupt, if I want to be really exact do I add one to whatever REG_VCOUNT is as that is the line I will be affecting?
_________________
Code:
CanIKickIt(YES_YOU_CAN);

#34219 - tepples - Sat Jan 15, 2005 7:02 pm

identitycrisisuk wrote:
So to do what I really want to do I'd either enable a VBlank interrupt and do what I want for line 0 there or just do it in my normal code loop after my wait for Vblank?

The latter might be simpler.

Quote:
And then in each HBlank interrupt, if I want to be really exact do I add one to whatever REG_VCOUNT is as that is the line I will be affecting?

Yes. For example, if you're in Hblank after line 87, you want to set up the scroll registers for line 88.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.