Sign in to follow this  

Scrolling the screen

This topic is 4674 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I wrote some Allegro code to display a randomly generated starfield and then to scroll it. Here's the code:
void move()
{
  int i, j;
  int temp[WIDTH];
  
  for(i=0;i<WIDTH;i++)
      temp[i] = getpixel(starbg,i,HEIGHT-1);
  
  blit(starbg,starbg,0,0,0,1,WIDTH,HEIGHT);
  
  for(i=0;i<WIDTH;i++)
      putpixel(starbg, i,0,temp[i]);
}

int main() 
{ 
 starteverything();
 buffer = create_bitmap(WIDTH,HEIGHT);
 
 stars();
 clear_bitmap(buffer);
 starbg = load_bmp("starscreen.bmp",NULL);
 
 blit(starbg,screen,0,0,0,0,WIDTH,HEIGHT);
 
 do{
    move();
    blit(starbg,screen,0,0,0,0,WIDTH,HEIGHT);
   }while(!key[KEY_ESC]);
 
 destroy_bitmap(starbg);
 destroy_bitmap(buffer);
 allegro_exit();
 return 0;     
}     

END_OF_MAIN();

Well that's as much of the code that matters anyway. Believe it or not, this code works just fine. The only problem is it's too slow. There must be a faster way to do this? I mean it's smooth and it delivers the correct effect, but I'm sure I could be doing this more effectively. So how do I? Thanks in advance.

Share this post


Link to post
Share on other sites
I haven't used allegro, but some general advice would be to make use of the position parameters in blit(). Don't modify the bitmap pixel-by-pixel, but instead blit the bitmap twice.

Say your bitmap is 100x500 pixels. Create a variable "scroll" that indicates the number of pixels the bitmap will be shifted by. Blit the bitmap once from (0, -scroll) to (100, 500-scroll). This will draw the bitmap undistorted, but positioned so you only see the bottom part of it.

Then blit it again from (0, 500-scroll) to (100, 1000-scroll). This will draw it again, but this time only the top part of it.

Then you can reset scroll once it reaches a certain point, to continue the looping graphics.

Share this post


Link to post
Share on other sites
I think you should probably just use 2 blits to the screen. If you really want to do it pixel by pixel; there's two important things. First, lock your bitmaps. This probably doesn't make much difference for a memory bitmap, but for a video bitmap like the screen it's insanely slow to try to draw otherwise. Note that the lock_bitmap function in Allegro does something else entirely, you use acquire_bitmap to lock a bitmap. Next, don't use getpixel or putpixel. They're slow, they need to check the bitmap's type, depth, size, clipping, etc. _putpixel?? and _getpixel?? (?? is the depth) are much faster, but have absolutely no error checking. You can also skip those functions entirely and use bitmap->line[y] to get to the bitmap's raw image data, which in theory is the fastest method, but a lot more work.

Share this post


Link to post
Share on other sites
EXCELLENT! Thanks guys. I just switched to blitting twice and it worked. All in about 4 lines of code.
One more question though...when I blit the background right to the screen it works fine, pretty quick, etc. But when I try to blit the 'two' backgrounds to a buffer and THEN blit the buffer to the screen, it slows to an agonizing crawl. Why is that, and how can I avoid it?

Share this post


Link to post
Share on other sites
Sign in to follow this