[AD] set_display_mode and screen update handling

[ Thread Index | Date Index | More lists.liballeg.org/allegro-developers Archives ]


As I mentioned before I had a couple functions lying around that would handle setting a video mode with a screen update method and an acompanying screen update function. I attached a C source file that has these functions.

- Kitty Cat
/* The bitmaps we'll be drawing to */
static BITMAP *page[3];
static int current_page;

#define DOUBLE_BUFFER  0x00000001
#define PAGE_FLIP      0x00000002
#define TRIPLE_BUFFER  0x00000004
#define WINDOWED       0x00000008
#define FULLSCREEN     0x00000010

/* Sets the requested mode, returning the bitmap you should start drawing on.
 * Pass 0 for all four arguments to properly shutdown the gfx mode.
 */
BITMAP *set_display_mode(int w, int h, int bpp, int flags)
{
   int driver = GFX_AUTODETECT;
   int vw = 0;
   int vh = 0;

   if(page[2])
      destroy_bitmap(page[2]);
   page[2] = NULL;
   if(page[1])
      destroy_bitmap(page[1]);
   page[1] = NULL;
   if(page[0])
      destroy_bitmap(page[0]);
   page[0] = NULL;

   if(!w && !h && !bpp && !flags)
   {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      return NULL;
   }

   /* Only platforms that have single-surface VRAM needs to have
    * virtual screen adjustment */
#ifdef ALLEGRO_VRAM_IS_SINGLE_SURFACE
   if((flags & TRIPLE_BUFFER))
   {
      vw = w;
      vh = h * 3;
   }
   else if((flags & PAGE_FLIP))
   {
      vw = w;
      vh = h * 2;
   }
#endif

   do {
      /* Windowed or fullscreen requested? */
      if((flags & FULLSCREEN))
      {
         flags &= ~FULLSCREEN;
         driver = GFX_AUTODETECT_FULLSCREEN;
      }
      else if((flags & WINDOWED))
      {
         flags &= ~WINDOWED;
         driver = GFX_AUTODETECT_WINDOWED;
      }

      /* Finally, set the mode and first vram page */
      set_color_depth(bpp);
      if(set_gfx_mode(driver, w, h, vw, vh) != 0)
         return NULL;
   } while((flags & (FULLSCREEN|WINDOWED)));

   page[0] = create_video_bitmap(SCREEN_W, SCREEN_H);
   if(!page[0])
   {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      return NULL;
   }

   /* If no buffering mode is specified, return the screen */
   if(!(flags&(DOUBLE_BUFFER|PAGE_FLIP|TRIPLE_BUFFER)))
      return page[0];

   /* Make sure we can do what's been requested */
   if((flags&TRIPLE_BUFFER) && (gfx_capabilities&GFX_CAN_TRIPLE_BUFFER))
   {
      page[1] = create_video_bitmap(SCREEN_W, SCREEN_H);
      page[2] = create_video_bitmap(SCREEN_W, SCREEN_H);
      if(page[1] && page[2])
         goto done;
   }

   if((flags&PAGE_FLIP) && (gfx_capabilities&GFX_CAN_SCROLL))
   {
      if(!page[1])
         page[1] = create_video_bitmap(SCREEN_W, SCREEN_H);
      if(page[1])
         goto done;
   }

   if(page[1])
      destroy_bitmap(page[1]);
   page[1] = NULL;

   if((flags&DOUBLE_BUFFER))
      page[1] = create_bitmap(SCREEN_W, SCREEN_H);

   if(!page[1])
   {
      destroy_bitmap(page[0]);
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      return NULL;
   }

done:
   current_page = 1;
   return page[current_page];
}


/* Displays what was drawn to the page last returned by this function. If
 * vs is true, vsync() will be called before blitting in double buffer
 * mode. Returns the next bitmap you should start drawing on.
 */
BITMAP *show_page(int vs)
{
   if(page[2])
   {
      while(poll_scroll())
         ;
      request_video_bitmap(page[current_page]);
      current_page = (current_page+1) % 3;
   }
   else if(is_video_bitmap(page[1]))
   {
      show_video_bitmap(page[current_page]);
      current_page ^= 1;
   }
   else
   {
      if(vs) vsync();
      blit(page[1], page[0], 0, 0, 0, 0, page[1]->w, page[1]->h);
   }

   return page[current_page];
}

/* Returns the current screen bitmap buffer. This is not gauranteed to remain
 * constant across show_page() calls. */
BITMAP *get_screen(void)
{
   if(page[2])
      return page[(current_page+2) % 3];

   if(!page[1])
      return page[0];

   if(is_video_bitmap(page[1]))
      return page[current_page^1];

   return page[1];
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/