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 > Hblanks

#30407 - mr_square - Wed Dec 01, 2004 12:09 am

Hi all. I'm currently looking at manipulating my background scroll values during the Hblank period to produce a typical wave'y effect (specifically I'm trying to make some water look as if it is flowing)

I've read up on some of the topics on here, but I'm still a bit confused about how to actually manipulate stuff during the hblank period. From what I can gather, REG_VCOUNT increases after each horizontal line, until it gets to 160, at which point its not drawing to the screen and you can manipulate everything freely.

I currently wait for a VSync using:

Code:

while((volatile u16)REG_VCOUNT != 160)
    {
        AAS_DoWork();
    }


(I'm using the AAS audio mixer, which is the function being called there).

To calculate an Hblank would you just do something like
Code:
while((volatile u16)REG_VCOUNT < 160)

and then alter the scroll values depending on which hBlank you were on?

That seems a bit simple, so I'm sure it can't be right (it certainly doesn't do anything when I try it in my code). Also, I hear people saying you need to specifically enable hblank interrupts - how do you do this? I assumed it was all just automatically tied to REG_VCOUNT.

#30411 - identitycrisisuk - Wed Dec 01, 2004 1:04 am

Hi, strangely enough I was looking at doing the same effect myself the other day, to make my fog background layer wibble. I didn't get it working as I started to get slowdown (on hardware!) and thought it was finally time to optimise my crappy background scrolling (which I think I've got now). I was following some interrupt stuff, which wasn't too bad though to make it really of much use you need to write an interrupt handler, which a lot of people seem to say should be in asm :s

So anyway, this is what I've got:
Code:
int offset = 0;

void IrqHandler(void)
{
   int temp = offset & 7;
   ++offset;
   REG_BG1HOFS = temp;
   REG_IF = REG_IF;
}

IrqHandler is what you do each HBlank, that's just something really nasty that will make your background look all jaggerdy. offset is a global. You need the REG_IF = REG_IF at the end, even though it looks a bit pointless.
Code:
REG_IRQ_HANDLER = IrqHandler;
REG_DISPSTAT = (1<<4);
REG_IE = (1<<1);
REG_IME = 1;

This is before I enter my main loop, first you set the IRQ_HANDLER register to point to the function you are using to handle interrupts. I didn't actually have this defined and had to add it, if you're in the same boat it's:
Code:
#define REG_IRQ_HANDLER   (*(fp*)0x3007FFC)

Where fp is:
Code:
typedef void (*fp)(void);

The REG_DISPSTAT thing is where you say you want to enable HBlank interrupts erm, and so is RE_IE from what I can get from the Register spec list I have at the moment. I know there's a differerence and you do need both. Then REG_IME is the master interrupts enable option type thingy. That code works, seems to look horrible on emulator but looks okay on hardware, not quite sure why....
_________________
Code:
CanIKickIt(YES_YOU_CAN);

#30422 - mr_square - Wed Dec 01, 2004 2:21 am

Wow - thanks man, that helped a lot, and I understand some foreign code that I didn't before, which is nice. In case anyone is interested:


I'm using the AAS Audio Mixer, which provides its own interrupt handler function, so it seems that REG_IRQ_HANDLER is already loaded up with a pointer to that funtion. I just added an 'if' statement in the function to check if it was the HBlank interrupt that was being detected, and then added identityCrisis' code to do the wibbly background effect.


REG_DISPSTAT = (1<<4);
REG_IE = (1<<1);
REG_IME = 1;

These lines gave me some grief, as they screwed up the sound completely, but I figured that they were probably overwriting settings that the AAS mixer had already set them up with. I just 'or'ed the current values of the registers with those new ones, and everything works perfectly :)

#30459 - identitycrisisuk - Wed Dec 01, 2004 11:55 am

Kewl, glad to be of help. Should have thought that you'd already have interrupts on if you're using sound. If it's that easy to write your own interrupt handling on top of AAS's I might have to try it sometime, it would take me a long time to learn enough ASM to write a very optimised audio mixer and interrupt handler. You probably don't need the REG_IME = 1 line at all now and you're right about ORing together the other ones.

The example I looked at had VBlank interrupts as well, which is probably a good idea to have in, that way you can set variables for effects each time a whole screen has been drawn, my way is a bit hacky. I'm guessing for a really nice water effect you'd use values from a sin/cos table. If I get round to doing it properly I'd need to add these values to REG_BG1HOFS as the background is also moving. I think REG_BG1HOFS is read only though so I'd have to put my data into some other variable.
_________________
Code:
CanIKickIt(YES_YOU_CAN);