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 > flickering in mode 3

#115613 - meth - Wed Jan 17, 2007 10:37 pm

hi!
Im quite new to programming gba and have tested a line drawing routine which runs perfect. But when clearing the screen every frame its just flickering and too slow!

Code:

void WaitForVblank(void)
{
   while(! (REG_DISPSTAT & DISPSTAT_VB));
   while(REG_DISPSTAT & DISPSTAT_VB);
}

void ClrScreen(void)
{
   int i;
   for(i = 0; i < SCREEN_HEIGHT * SCREEN_WIDTH; i++)
      FrontBuffer[i] = 0;
}


and the mainloop:
Code:

   while(1)
   {
      WaitForVblank();
      ClrScreen();
      DrawLine(x1,4,x2=72,y2=75,32-1); //x1, y1, x2, y2, color
      
      if(x1 > SCREEN_WIDTH)
         x1 = 1;
      x1++;
   }


Can someone please help here? In the pern Project one example with rotating a box is used, and that one is running quite good, and uses the same code (without any double buffering etc).


ps I am using VisualBoy Advance version 1.7.1

#115617 - Miked0801 - Wed Jan 17, 2007 10:57 pm

A few iedas.

1. Are you compiling optimized?
2. What is FrontBuffer declared as? If it's a u8, then your clear routine will be real slow. If it's u16, then you are clearing too much screen with your loop. Either way, DmaClear would be much better.
3. Don't assign x2 and y2 every tic inside the draw command, place it outside the while loop and only assign them once.

#115619 - meth - Wed Jan 17, 2007 11:22 pm

thanks for the tip to change the values to outside the loop!

for compiling Im using this script:
gcc -o source.elf source.c -lm
objcopy -O binary source.elf source.bin

the frontbuffer has this define (from regs.h)
#define FrontBuffer ((u16*)0x6000000)

how could I clear too much? My idea was to clear the whole screen (even if thats not optimized in this caze), but am I clearing more than that?

#115625 - Miked0801 - Thu Jan 18, 2007 12:29 am

Nah, if it's declared that way, it is fine (for what it is). DmaClear or DmaCopy would still be much better.

To compile optimized, add a '-O3' to your command line. You should also get used to having warnings turned on with -Wall and -W (treat warnings as errors) on as well.

#115657 - thegamefreak0134 - Thu Jan 18, 2007 6:16 am

I would actually advise against the warning flags, as I've had some warnings show up inlibraries I've imported (warnings mind, not actual errors) and fixing something you didn't even write is particularly difficult to do.

By "flickery" do you mean to say that the clear leaves artifacts on the screen? (This is rather hard to describe if you haven't seen it, but it looks like it takes it an awfully long time to draw one frame, or can be described as "tearing lines" going from the top to the bottom of the screen.) If so, this just means that your routine cannot complete the entire screen's worth of work in the same ammount of time it takes the GBA to draw one frame. In short, your routine is too slow.

DMA of some sort is really your friend, and TONC has some very nice macros to make this type of copy simple and painless. Basically, a DMA copy is done in hardware, unlike your for loop, which is handled by software. Using it will clear the screen and give you CPU time to spare.

We also have some issues to clear up with your WaitForVSync loop, but I'll let someone else yell at you for that, I don't have the proper routine in front of me at the moment.

-thegamefreak

PS: This is normal. Learning is a normal part of life.
_________________
What if the hokey-pokey really is what it's all about?

[url=http:/www.darknovagames.com/index.php?action=recruit&clanid=1]Support Zeta on DarkNova![/url]

#115658 - tepples - Thu Jan 18, 2007 6:42 am

Miked0801 wrote:
To compile optimized, add a '-O3' to your command line.

I used to use -O3, but when a GCC upgrade caused my C code to overflow IWRAM due to more aggressive unrolling in the newer version, I switched to -O2 for a better balance among size, speed, and compilation time.

Miked0801 wrote:
You should also get used to having warnings turned on with -Wall and -W (treat warnings as errors) on as well.

Actually, -Wextra (for which -W is now an alias) enables a set of warnings that -Wall does not. The switch that treats warnings as errors is -Werror. (Source: GCC Manual: Warning Options)

thegamefreak0134 wrote:
I would actually advise against the warning flags, as I've had some warnings show up inlibraries I've imported (warnings mind, not actual errors) and fixing something you didn't even write is particularly difficult to do.

What specific library gives you warnings when you arm-eabi-gcc -Wall -O2?

thegamefreak0134 wrote:
In short, your routine is too slow.

DMA of some sort is really your friend

For copies, yes; for clears, CpuFastSet() is faster.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#115695 - meth - Thu Jan 18, 2007 1:16 pm

thanks to all of you! Will try out what I've learned!

#115696 - keldon - Thu Jan 18, 2007 1:19 pm

Sometimes it's much better (and quicker) to go back and start from the beginning rather than spend hours trying to fix the problem. Maybe follow the tonc gba tutorials and when you approach bitmaps you will have the right method!