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.

Coding > Metroid Fusion

#7889 - NovusAmor - Fri Jun 27, 2003 1:26 pm

Does anyone know how they did the wavy water effect in Sector 4. If you go under water and look at the bottom layer the image sways back and forth. Are they using HBlank to achieve it? If so, do they scroll the layer back and forth each HBlank?
_________________
Robert
Senior Programmer
NeoPong Software, Inc
www.neopong.com

#7894 - tepples - Fri Jun 27, 2003 6:07 pm

Effects like this in Donkey Kong Country are done with hblank DMA to the scroll registers, possibly with a vcount interrupt to switch palettes.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#7942 - NitroSR - Sun Jun 29, 2003 3:00 am

I've been toying with this effect myself. I quickly put together a simple scroller that will allow me to scroll across arbitrarily sized maps at any speed on a 256x256 map, and I figured I could have some fun with HBLANK effects.

Using the interrupt table method, I wrote an HBLANK handler that does as follows. Using a sine table, counter variable, and the current X/Y coordinates, I write the following to my chosen layer's horizontal offset register.


void HBLANK(void) {

REG_BG0HOFS = cur_x + (SIN(g_tempangle) >> g_damplitude);
g_tempangle += g_frequency;

REG_IF = INT_HBLANK;

} // ends HBLANK interrupt handler

Now, there's a reason why I have a variable called g_tempangle. If you keep the code as-is, the first frame will skew each line according to the sine wave. But in the next frame, g_tempangle will have been incremented by (g_frequency * 160), causing the wave to move too rapidly, so you need another variable that stores the angle where the wave should start at the top of the screen. So, every V_BLANK you should update a variable called g_angle by a constant amount, and then copy this new value into g_tempangle. I use a sine table with an range of -256 to 256 and 256 angles, so by shifting right by some constant I can reduce the amplitude of the sign wave to some desired power of 2. Essentially, the higher g_frequency the tighter the wave, the higher g_damplitude the less the wave will cause distortion.

Experiment with the variables, and also try applying the same trick to the V_OFFSET registers... Trust me, you won't be disapointed.