Skip to content

Improving the WaitForVBlank function

LOuroboros edited this page Jan 6, 2021 · 7 revisions

The credits for this tutorial belong to DizzyEggg.

In both, Pokémon FireRed/LeafGreen and Pokémon Emerald, Game Freak modified the WaitForVBlank function present in Pokémon Ruby/Sapphire.

What this function normally does is to put the GBA's CPU in Sleep Mode each time a pixel has been drawn on the screen. While in that state, the CPU prioritizes saving its power over everything else.

By telling the CPU not to enter Sleep Mode, we make the GBA use its full power at all times.

The easiest way to do so, is by copying and pasting the function directly from Ruby and Sapphire, which means modifying the function like this:

static void WaitForVBlank(void)
{
    gMain.intrCheck &= ~INTR_FLAG_VBLANK;
-   while (!(gMain.intrCheck & INTR_FLAG_VBLANK))
-       ;
+   VBlankIntrWait();
}

Alternatively, we can do what the VBlankIntrWait function does in a more direct manner, which is unnoticeably faster.

static void WaitForVBlank(void)
{
    gMain.intrCheck &= ~INTR_FLAG_VBLANK;
-   while (!(gMain.intrCheck & INTR_FLAG_VBLANK))
-       ;
+   asm("swi 0x5");
}

Save, build a ROM, and so the game will utilize the full power of the GBA's CPU in order to draw things on screen. The easiest way to notice this is while running the game on a GBA emulator with a FastForward feature implemented.

Clone this wiki locally