Code Search for Developers
 
 
  

exupdate.c from Allegro game programming library at Krugle


Show exupdate.c syntax highlighted

/*
 *    Example program for the Allegro library, by Shawn Hargreaves.
 *
 *    This program demonstrates how to support double buffering, page
 *    flipping, and triple buffering as options within a single program,
 *    and how to make things run at a constant rate no matter what the
 *    speed of your computer.
 */


#include "allegro.h"



/* number of video memory pages:
 *  1 = double buffered
 *  2 = page flipping
 *  3 = triple buffered
 */
int num_pages;

int use_system_bitmaps;



/* counters for speed control and frame rate measurement */
volatile int update_count = 0;
volatile int frame_count = 0;
volatile int fps = 0;



/* timer callback for controlling the program speed */
void timer_proc(void)
{
   update_count++;
}

AL_END_OF_FUNCTION(timer_proc);



/* timer callback for measuring the framerate */
void fps_proc(void)
{
   fps = frame_count;
   frame_count = 0;
}

AL_END_OF_FUNCTION(fps_proc);



/* some rotation values for the graphical effect */
fixed r1 = 0;
fixed r2 = 0;
fixed r3 = 0;
fixed r4 = 0;



/* helper to draw four mirrored versions of a al_draw_triangle */
void kalid(AL_BITMAP *bmp, int x1, int y1, int x2, int y2, int x3, int y3, int r, int g, int b)
{
   al_draw_triangle(bmp, AL_SCREEN_W/2+x1, AL_SCREEN_H/2+y1, AL_SCREEN_W/2+x2, AL_SCREEN_H/2+y2, AL_SCREEN_W/2+x3, AL_SCREEN_H/2+y3, al_make_color(r, g, b));
   al_draw_triangle(bmp, AL_SCREEN_W/2-x1, AL_SCREEN_H/2+y1, AL_SCREEN_W/2-x2, AL_SCREEN_H/2+y2, AL_SCREEN_W/2-x3, AL_SCREEN_H/2+y3, al_make_color(r, g, b));
   al_draw_triangle(bmp, AL_SCREEN_W/2-x1, AL_SCREEN_H/2-y1, AL_SCREEN_W/2-x2, AL_SCREEN_H/2-y2, AL_SCREEN_W/2-x3, AL_SCREEN_H/2-y3, al_make_color(r, g, b));
   al_draw_triangle(bmp, AL_SCREEN_W/2+x1, AL_SCREEN_H/2-y1, AL_SCREEN_W/2+x2, AL_SCREEN_H/2-y2, AL_SCREEN_W/2+x3, AL_SCREEN_H/2-y3, al_make_color(r, g, b));
}



/* draws the current animation frame into the specified bitmap */
void draw_screen(AL_BITMAP *bmp)
{
   fixed c1 = al_fix_cos(r1);
   fixed c2 = al_fix_cos(r2);
   fixed c3 = al_fix_cos(r3);
   fixed c4 = al_fix_cos(r4);
   fixed s1 = al_fix_sin(r1);
   fixed s2 = al_fix_sin(r2);
   fixed s3 = al_fix_sin(r3);
   fixed s4 = al_fix_sin(r4);

   al_acquire_bitmap(bmp);

   al_clear_bitmap(bmp);

   al_drawing_mode(DRAW_MODE_XOR, NULL, 0, 0);

   kalid(bmp, al_fix_to_int(c1*AL_SCREEN_W/3), al_fix_to_int(s1*AL_SCREEN_H/3),
	      al_fix_to_int(c2*AL_SCREEN_W/3), al_fix_to_int(s2*AL_SCREEN_H/3),
	      al_fix_to_int(c3*AL_SCREEN_W/3), al_fix_to_int(s3*AL_SCREEN_H/3),
	      127+al_fix_to_int(c1*127), 127+al_fix_to_int(c2*127), 127+al_fix_to_int(c3*127));

   kalid(bmp, al_fix_to_int(s1*AL_SCREEN_W/3), al_fix_to_int(c2*AL_SCREEN_H/3),
	      al_fix_to_int(s3*AL_SCREEN_W/3), al_fix_to_int(c4*AL_SCREEN_H/3),
	      al_fix_to_int(c3*AL_SCREEN_W/3), al_fix_to_int(s4*AL_SCREEN_H/3),
	      127+al_fix_to_int(s1*127), 127+al_fix_to_int(c4*127), 127+al_fix_to_int(s4*127));

   kalid(bmp, al_fix_to_int(al_fix_mul(s2, c3)*AL_SCREEN_W/3), al_fix_to_int(c1*AL_SCREEN_H/3),
	      al_fix_to_int(c4*AL_SCREEN_W/3), al_fix_to_int(al_fix_mul(c2, s3)*AL_SCREEN_H/3),
	      al_fix_to_int(al_fix_mul(c3, s4)*AL_SCREEN_W/3), al_fix_to_int(s1*AL_SCREEN_H/3),
	      127+al_fix_to_int(s2*127), 127+al_fix_to_int(c3*127), 127+al_fix_to_int(s3*127));

   al_drawing_mode(DRAW_MODE_SOLID, NULL, 0, 0);

   al_text_mode(-1);

   if (num_pages == 1) {
      if (use_system_bitmaps)
	 al_put_text(bmp, al_font_8x8, "Double buffered (system bitmap)", 0, 0, al_make_color(255, 255, 255));
      else
	 al_put_text(bmp, al_font_8x8, "Double buffered (memory bitmap)", 0, 0, al_make_color(255, 255, 255));
   }
   else if (num_pages == 2)
      al_put_text(bmp, al_font_8x8, "Page flipping (two pages of vram)", 0, 0, al_make_color(255, 255, 255));
   else
      al_put_text(bmp, al_font_8x8, "Triple buffered (three pages of vram)", 0, 0, al_make_color(255, 255, 255));

   al_put_text(bmp, al_font_8x8, gfx_driver->name, 0, 16, al_make_color(255, 255, 255));

   al_printf_text(bmp, al_font_8x8, 0, 32, al_make_color(255, 255, 255), "FPS: %d", fps);

   al_release_bitmap(bmp);
}



/* called at a regular speed to update the program state */
void do_update(void)
{
   r1 += al_float_to_fix(0.5);
   r2 += al_float_to_fix(0.6);
   r3 += al_float_to_fix(0.11);
   r4 += al_float_to_fix(0.13);
}



int main(int argc, char *argv[])
{ 
   AL_PALETTE pal;
   AL_BITMAP *bmp[3];
   int card = AL_GFX_AUTODETECT;
   int w, h, bpp, page, i;

   allegro_init();

   /* check command al_draw_line arguments */
   if (argc == 2)
      num_pages = atoi(argv[1]);
   else
      num_pages = 0;

   if (num_pages == 4) {
      num_pages = 1;
      use_system_bitmaps = TRUE;
   }
   else
      use_system_bitmaps = FALSE;

   if ((num_pages < 1) || (num_pages > 3)) {
      al_show_message("\nUsage: 'exupdate num_pages', where num_pages is one of:\n\n"
		      "1 = double buffered (memory bitmap)\n\n"
		      "    + easy, reliable\n"
		      "    + drawing onto a memory bitmap is very fast\n"
		      "    - blitting the finished image to the al_screen can be quite slow\n\n"
		      "2 = page flipping (two pages of video memory)\n\n"
		      "    + avoids the need for a memory to al_screen al_blit of the completed image\n"
		      "    + can use hardware acceleration when it is available\n"
		      "    - drawing directly to vram can be slower than using a memory bitmap\n"
		      "    - requires a card with enough video memory for two al_screen pages\n"
		      "    - some VESA drivers have nasty bugs in the scrolling functions\n\n"
		      "3 = triple buffered (three pages of video memory)\n\n"
		      "    + like page flipping, but faster and smoother\n"
		      "    - requires a card with enough video memory for three al_screen pages\n"
		      "    - only possible in mode-X (not win95), or with VBE 3.0 or VBE/AF\n\n"
		      "4 = double buffered (system bitmap)\n\n"
		      "    + as easy as normal double buffering\n"
		      "    + system bitmaps can be hardware accelerated on some platforms\n"
		      "    - drawing to system bitmaps is sometimes slower than memory bitmaps\n\n");
      return 1;
   }

   /* set up Allegro */
   al_install_keyboard();
   al_install_timer();
   al_install_mouse();
   if (al_set_gfx_mode(AL_GFX_SAFE, 320, 200, 0, 0) != 0) {
      al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
      al_show_message("Unable to set any graphic mode\n%s\n", al_error);
      return 1;
   }
   al_set_palette(al_desktop_palette);

   w = AL_SCREEN_W;
   h = AL_SCREEN_H;
   bpp = al_bitmap_color_depth(al_screen);
   if (!al_select_gfx_mode(&card, &w, &h, &bpp))
      return 0;

   al_set_color_depth(bpp);

   if (al_set_gfx_mode(card, w, h, 0, 0) != 0) {
      al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
      al_show_message("Error setting graphics mode\n%s\n", al_error);
      return 1;
   }

   al_generate_332_palette(pal);
   pal[0].r = pal[0].g = pal[0].b = 0;
   al_set_palette(pal);

   switch (num_pages) {

      case 1:
	 /* double buffering setup */
	 if (use_system_bitmaps)
	    bmp[0] = al_create_system_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 else
	    bmp[0] = al_create_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 break;

      case 2:
	 /* page flipping setup */
	 bmp[0] = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 bmp[1] = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 break;

      case 3:
	 /* triple buffering setup */
	 if (!(al_gfx_capabilities & AL_GFX_CAN_TRIPLE_BUFFER))
	    al_enable_triple_buffer();

	 if (!(al_gfx_capabilities & AL_GFX_CAN_TRIPLE_BUFFER)) {
	    al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);

	    #ifdef ALLEGRO_DOS
	       al_show_message("This driver does not support triple buffering\n\nTry using mode-X in clean DOS mode (not under Windows)\n");
	    #else
	       al_show_message("This driver does not support triple buffering\n");
	    #endif

	    return 1;
	 }

	 bmp[0] = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 bmp[1] = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 bmp[2] = al_create_video_bitmap(AL_SCREEN_W, AL_SCREEN_H);
	 break;
   }

   for (i=0; i<num_pages; i++) {
      if (!bmp[i]) {
	 al_set_gfx_mode(AL_GFX_NONE, 0, 0, 0, 0);
	 al_show_message("Unable to create %d video memory pages\n", num_pages);
	 return 1;
      }
   }

   /* install timer handlers to control and measure the program speed */
   LOCK_VARIABLE(update_count);
   LOCK_VARIABLE(frame_count);
   LOCK_VARIABLE(fps);
   LOCK_FUNCTION(timer_proc);
   LOCK_FUNCTION(fps_proc);

   al_create_timer(timer_proc, BPS_TO_TIMER(60));
   al_create_timer(fps_proc, BPS_TO_TIMER(1));

   page = 1;

   /* main program loop */
   while (!al_key_pressed()) {

      /* draw the next frame of graphics */
      switch (num_pages) {

	 case 1:
	    /* draw onto a memory bitmap, then al_blit to the al_screen */
	    draw_screen(bmp[0]);
	    al_vsync();
	    al_blit(bmp[0], al_screen, 0, 0, 0, 0, AL_SCREEN_W, AL_SCREEN_H);
	    break;

	 case 2:
	    /* flip back and forth between two pages of video memory */
	    draw_screen(bmp[page]);
	    al_show_video_bitmap(bmp[page]);
	    page = 1-page;
	    break;

	 case 3:
	    /* triple buffering */
	    draw_screen(bmp[page]);

	    do {
	    } while (al_poll_scroll());

	    al_request_video_bitmap(bmp[page]);
	    page = (page+1)%3;
	    break;
      }

      /* update the program state */
      while (update_count > 0) {
	 do_update();
	 update_count--;
      }

      frame_count++;
   }

   for (i=0; i<num_pages; i++)
      al_destroy_bitmap(bmp[i]);

   return 0;
}

AL_END_OF_MAIN();




See more files for this project here

Allegro game programming library

Allegro is a cross-platform library intended for use in computer games and other types of multimedia programming.

Project homepage: http://sourceforge.net/projects/alleg
Programming language(s): Assembly,C,Shell Script
License: other

  allegro.pcx
  ex12bit.c
  ex3buf.c
  ex3d.c
  exaccel.c
  exalpha.c
  example.dat
  example.h
  examples.txt
  exbitmap.c
  exblend.c
  excamera.c
  excolmap.c
  excustom.c
  exdata.c
  exdbuf.c
  exdodgy.c
  exexedat.c
  exfixed.c
  exflame.c
  exflip.c
  exgui.c
  exhello.c
  exjoy.c
  exkeys.c
  exlights.c
  exmem.c
  exmidi.c
  exmouse.c
  expal.c
  expat.c
  exquat.c
  exrgbhsv.c
  exsample.c
  exscale.c
  exscn3d.c
  exscroll.c
  exshade.c
  exspline.c
  exsprite.c
  exstars.c
  exstream.c
  exswitch.c
  extimer.c
  extrans.c
  extruec.c
  exunicod.c
  exupdate.c
  exxfade.c
  exzbuf.c
  mysha.pcx
  planet.pcx
  running.dat
  running.h
  unifont.dat